JDBC 全解析:从入门到实战,掌握数据库交互核心技术

JDBC

JDBC概述

概述
  • java database connectivity java数据库的连接

  • 目的使用java的代码来操作数据库

  • 需要使用jdbc(jav数据库的连接)规范来操作数据

jdbc的规范

  • jdbc是一套接口规范

  • jdbc的实现类都是由各个数据库的生产商来提供的

  • 只要学会了jdbc的接口和方法,就可以了

驱动

  • 数据传输的桥梁

  • 驱动指的是各个数据库生产商提供的是是实现类

  • 需要来使用实现类,需要导入Mysql提交的驱动的jar包(千万不能忘记)

    • 需要导入mysql-connector-java-5.1.13-bin.jar

jdbc开发的入门步骤

JDBC的快速入门
  1. 准备工作:创建数据库,创建表结构,添加若干条数据。

  2. 准备编写入门的程序

    ,需求:查询数据库中的数据?

    1. 加载驱动类(先导入开发的jar包,驱动包)

    2. 获取到连接(操作数据库,连接上数据库),过程中传入连接主机地址、用户名和密码

    3. 执行一些SQL语句(执行查询的SQL语句)

    4. 遍历结果集(查询的数据全部都封装到结果集中了)

    5. 释放资源(刚才连接的那些没有用的资源)

  3. MySQL的快速入门的开发的步骤

    • 了解记忆开发的步骤
  4. 先创建day07的数据库和表结构。

    XML 复制代码
     create database day07;
     use day07;
     create table t_user(
     id int primary key auto_increment,
     username varchar(30),
     password varchar(30),
     email varchar(30)
     );
     ​
     insert into t_user values (null,'aaa','123','[aaa@163.com](mailto:aaa@163.com)');
     insert into t_user values (null,'bbb','456','[bb@163.com](mailto:bb@163.com)');
     insert into t_user values (null,'ccc','789','[ccc@163.com](mailto:ccc@163.com)');
  5. 需求

    • 查询的功能,把t_user表中的所有的数据全部都查询出来,显示到控制台上!!
  6. 开发的步骤

    • 加载驱动使用DriverManager类

    • 获取连接,返回Connection接口,说明连接上数据库的服务器

    • 执行sql语句

      • 编写sql语句

      • 获取能执行sql语句的对象(Statement接口)

    • 如果执行的查询的语句,返回的结果,封装ResultSet接口中,遍历该接口

    • 释放资源(调用close()方法)

JDBC相关的接口和API(重要的方法必须掌握)
DriverManager类(驱动)
  1. DriverManager

    • 使用DriverManager来管理JDBC的驱动的实现类
  2. 作用

    • 加载驱动

      java 复制代码
       static void registerDriver(Driver driver)
      • 参数:传入的真正的参数其实是MySQL提供Driver的类

      • 传入的参数

        java 复制代码
         new Driver()

        这种方式不是特别好

        • 过于依赖某一个实现类

        • 驱动的jar包会加载两次(通过看源代码)

      • 解决上述的两个问题

        java 复制代码
        Class.forName("com.mysql.jdbc.Driver"); 

        注册驱动,切换一种写法,反射代码。加载com.mysql.jdbc.Driver类,只要该类一加载,static代码块就会执行(注册驱动)

    • 获取连接

      java 复制代码
       static Connection getConnection(String url, String user, String password)
      • 参数有3个

        • 第一个参数:

          复制代码
           jdbc:mysql://localhost:3306/day07

          (背下来)

          • jdbc -- 代表的主协议

          • mysql -- 子协议(有可能变化的)

          • localhost -- 主机

          • 3306 -- 默认的端口号

          • day07 -- 数据库

        • 如果访问的是本地的自己的数据库,那么localhost: 3306就可以省略不写

          • mysql的命令 -uroot -proot

          • JDBC简写:jdbc:mysql://day07

        • 第二个参数:root(用户名)

        • 第三个参数:root(密码)

  3. 总结

    • 管理驱动的

    • 作用

      • 加载驱动

        java 复制代码
         Class.forName("com.mysql.jdbc.Driver");
      • 获取连接

        java 复制代码
         getConnection("jbc:mysql://day07","root","密码")
Connection接口(链接)
  1. Connection

    • 代表的数据库的连接,非常重要,并且连接比较稀有,用完一定要释放它
  2. 作用

    • 能获取到执行SQL语句的对象(获取Statement接口)

      • Statement createStatement() -- 获取到Statement接口

      • PreparedStatement prepareStatement(String sql) -- 获取到PreparedStatement接口,对象非常重要的,防止SQL注入的漏洞。

    • 管理事务

      • void setAutoCommit(boolean autoCommit) -- 开启事务

      • void commit() -- 提交事务

      • void rollback() -- 回滚事务

  3. 总结

    • 获取能执行SQL语句对象的方法

      • Statement createStatement()

      • PreparedStatement prepareStatement(String sql)

    • 只需要知道Connection接口可以管理事务就可以了!!

Statement接口(能执行SQL语句)
  1. Statement接口
  • 能执行SQL语句的对象
  1. 作用
  • 能执行SQL语句

    • ResultSet executeQuery(String sql) -- 执行查询SQL语句的方法

    • int executeUpdate(String sql) -- 能执行增删改的SQL语句

  • 能执行批处理

    • void addBatch(String sql) -- 把SQL语句添加到批处理中

    • void clearBatch() -- 清除批处理

    • int[] executeBatch() -- 执行批处理

  1. 总结
  • 就是能执行SQL语句

  • 作用

    • 执行SQL语句

    • 执行批处理

ResultSet接口(代表结果集)
  1. ResultSet接口
  • 代表的是结果集,执行的是查询的SQL语句,把查询的数据的表格封装到ResultSet接口中,通过遍历该接口,获取到查询的结果!
  1. 总结
  • 封装数据

    • ResultSet接口使用表格的方式来封装数据。

    • 内部维护一个游标,默认指向的是第一行数据之前。

    • 调用next()方法来向下移动游标,移动到某一行,获取该行的数据。

    • 注意:游标默认只能向下移动。

  • 获取值

    • 根据字段的类型,调用不同的方法。

    • 例如:

      • 如果字段是int或者bigint,使用getInt()或者getLong()

      • 如果字段是varchar char类,使用getString()

      • 使用getObject()获取任何类型的数据,自己强转。

    • 获取数据的方法都是重载的:

      • getInt(int index) -- 通过下标值来取值,默认从1开始。

      • getInt(String s) -- 通过字段的名称来取值,比较常用的。

释放资源(必须要做的)
  1. 连接的对象必须要释放。

  2. 释放资源的代码一般会在finally代码块中释放。

    • 一定会执行的。
  3. 释放的代码的标准:

java 复制代码
 if(conn != null){
     try {
         // 释放资源
         conn.close();
     } catch (SQLException e) {
         e.printStackTrace();
     }
     conn = null;
 }

公共类 DBConnection,用于管理数据库连接工具类

java 复制代码
package com.qcby.db;
 // 导入 java.sql 包中的 Connection 和 DriverManager 类,用于数据库连接操作
 import java.sql.Connection;
 import java.sql.DriverManager;
 ​
 public class DBConnection {
 ​
     String driver = "com.mysql.jdbc.Driver";  //5...
     //String driver = "com.mysql.cj.jdbc.Driver";//8...
     // 定义字符串变量 driver,指定 MySQL 5.x 版本的 JDBC 驱动类名
     // 注释中提到如果是 MySQL 8.x 及以上版本,应使用 "com.mysql.cj.jdbc.Driver"
     String url = "jdbc:mysql://127.0.0.1:3306/javaweb";
      // 定义字符串变量 url,指定数据库的连接地址
     // 这里表示连接本地(127.0.0.1)3306 端口上的名为 javaweb 的数据库
     String user = "root";
     // 定义字符串变量 user,指定数据库连接的用户名,这里为 roo
     String password = "root";//密码
  // 定义字符串变量 password,指定数据库连接的密码,这里为 root
     public Connection conn;
 // 定义一个公共的 Connection 类型变量 conn,用于保存数据库连接对象
     public DBConnection() {
 ​
         try {
             Class.forName(driver);
             // 使用 Class.forName() 方法加载指定的数据库驱动类
             // 这一步是为了将驱动类注册到 DriverManager 中
             conn = (Connection) DriverManager.getConnection(url, user, password);//
 // 通过 DriverManager 的 getConnection() 方法建立与数据库的连接
             // 将返回的 Connection 对象赋值给成员变量 conn
  
             // if(!conn.isClosed())
             // System.out.println("Succeeded connecting to the Database!");
         } catch (Exception e) {
             e.printStackTrace();
             // 捕获并打印可能出现的异常,例如驱动类加载失败、数据库连接失败等
         }
     }
 ​
     public void close() {
          // 定义一个公共方法 close(),用于关闭数据库连接
         try {
             this.conn.close();
             // 调用 conn 的 close() 方法关闭数据库连接
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 ​
 }
复制代码

使用jdbc对数据库进行增删改查工具类

java 复制代码
 package com.qcby.db;
 ​
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 public class MysqlUtil {
 ​
     //添加
     public static int add(String sql) {
         int i=0;
         DBConnection db = new DBConnection();
         // 创建一个 DBConnection 对象,用于建立数据库连接
         try {        
             PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(sql);
             // 使用传入的 SQL 语句创建一个 PreparedStatement 对象,用于执行预编译的 SQL 语句
             i=preStmt.executeUpdate();
             // 执行 SQL 语句,返回受影响的行数
             preStmt.close();
             // 关闭 PreparedStatement 对象,释放资源
             db.close();
           // 关闭数据库连接
         } catch (Exception e) {
             e.printStackTrace();
         }
         return i;
         // 返回受影响的行数
     }
 ​
     //修改
     public static int update(String sql) {
         int i =0;
         DBConnection db = new DBConnection();
         try {
             PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(sql);
             i = preStmt.executeUpdate();
             preStmt.close();
             db.close();
         } catch (SQLException e) {
             e.printStackTrace();
         }
         return i;
         // 逻辑与 add 方法类似,用于执行修改操作,返回受影响的行数
     }
     
     //删除
     public static int del(String delstr) {
         int i=0;
         DBConnection db = new DBConnection();
         try {    
             PreparedStatement preStmt = (PreparedStatement) db.conn.prepareStatement(delstr);
             i=preStmt.executeUpdate();
             preStmt.close();
             db.close();
         } catch (SQLException e){
             e.printStackTrace();
         }
         // 逻辑与 add、update 方法类似,用于执行删除操作,返回受影响的行数
         return i;
     }
 ​
     //查数量
     public static int getCount(String sql) {
         int sum = 0;
         DBConnection db = new DBConnection();
         try {
             Statement stmt = (Statement) db.conn.createStatement();
             // 创建一个 Statement 对象,用于执行静态 SQL 语句
             ResultSet rs = (ResultSet) stmt.executeQuery(sql);
             // 执行 SQL 查询,返回结果集
             while (rs.next()) {
                 sum += rs.getInt(1);
                 // 遍历结果集,将第一列的值累加到 sum 中
             }
             rs.close();
             // 关闭结果集
             db.close();
              // 关闭数据库连接
         } catch (Exception e) {
         }
         return sum;
         // 返回查询到的数量总和
     }
 ​
     //查找,返回json格式的数据
     public static String getJsonBySql( String sql,String[] colums){
         ArrayList<String[]>  result = new ArrayList<String[]>();
         DBConnection db = new DBConnection();
         try {
             Statement stmt = (Statement) db.conn.createStatement();
             ResultSet rs = (ResultSet) stmt.executeQuery(sql);
             while(rs.next()){
                 String[] dataRow = new String[colums.length];
                 for( int i = 0; i < dataRow.length; i++ ) {
                     dataRow[i] = rs.getString( colums[i] );
                     // 从结果集中获取指定列的值,存入 dataRow 数组
                 }
                 result.add(dataRow);
                 // 将 dataRow 数组添加到 result 列表中
             }
             rs.close();
             db.close();
         } catch (SQLException e) {
             e.printStackTrace();
         }
 ​
         return listToJson(result,colums);
         // 调用 listToJson 方法将结果列表转换为 JSON 字符串并返回
     }
 ​
     
    //将列表数据转换为json字符串的方法
     public static String listToJson( ArrayList<String[]> list,String[] colums) {
 ​
         String jsonStr = "{\"code\":0,\"msg\":\"ok\",\"data\":[";
                 for(int i = 0; i < list.size(); i++) {
                     String arr = "{";
                     for( int j = 0; j < list.get(0).length; j++) {
                         
                         if( list.get(i)[j] == null || "NULL".equals(list.get(i)[j])) {
                             arr += "\"" + colums[j] + "\":\"\"";
                         }else {
                             arr += "\"" + colums[j] + "\""+":" ;
                             arr +=  "\"" + list.get(i)[j].replace("\"","\\\"") + "\"";
                         }
                         
                         if( j < list.get(0).length - 1 ) {
                             arr += ",";
                         }
                     }
                     arr += "}";
                     if( i < list.size() - 1 ) {
                         arr += ",";
                     }
                     
                     jsonStr += arr;
                 }
                 jsonStr += "]}";
         
         return jsonStr;
     }
 ​
     
 ​
 }
 ​

SQL注入问题

java 复制代码
 //模拟登录的功能,通过用户名和密码从数据库中查询
 //演示sql注入的问题,漏洞,在已知用户名的情况下,通过sql语言关键字,登录系统。密码随意输入的
 //SQL注入产生原因是SQL语句的拼接,利用SQL关键字产生效果
 public class Test{
     public static void main(String[] args) {
         String result = login("aaa 'or' 1=1","123456sadfa")
     } 
     //模拟登录的功能
     pulbic string login(String username,String password) {
         Class.forName("com.mysql.jdbc.Driver");
          Connection coon = DriverManager.getConnection("jdbc:mysql://127.0.0.0:3306/javaweb");
         Statement stmt = coon.createStatement();
       ResultSet  res =    stmt.executeQuery("select * from user where username = '""+username+"' and password = '"+password +"'  ");
                    if(res.next()) {
                        return '登录成功'
                    } else {
                        return '登录失败'
                    }
                          if(res != null) {
                              res.close()
                          }  
                           if(stmt != null) {
                               stmt.close()
                           }    
                                               if(coon != null) {
                               coon.close()
                           }  
                                             
     }
 }
什么是 SQL 注入?

SQL 注入是一种常见的 Web 安全漏洞,攻击者通过在用户输入中插入恶意 SQL 代码,干扰或控制数据库查询逻辑,从而窃取、篡改或破坏数据

示例

  • 正常查询:SELECT * FROM users WHERE username = 'admin' AND password = '123456'

  • 攻击者输入:' OR '1'='1(在用户名或密码字段中)

  • 恶意 SQL:

    复制代码
     SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
    • 由于 '1'='1' 永远为真,攻击者可能绕过登录验证,直接获取所有用户数据。
SQL 注入的危害**
  1. 数据泄露:窃取敏感信息(如用户密码、信用卡号)。

  2. 数据篡改:修改或删除数据库中的数据。

  3. 数据库破坏 :执行 DROP TABLE 等危险操作,导致服务瘫痪。

  4. 权限提升:获取数据库管理员权限,进一步攻击系统

SQL 注入的常见场景**
(1) 用户登录验证
  • 攻击者输入恶意用户名或密码,绕过身份验证。

  • 示例

    objectivec 复制代码
     SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx'
    • -- 是 SQL 注释符,导致后续条件被忽略。
(2) 搜索功能
  • 攻击者在搜索框中输入恶意 SQL,如:

    objectivec 复制代码
     SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx'
    • 可能泄露其他表的数据。
(3) 动态 SQL 拼接
  • 如果代码直接拼接用户输入到 SQL 语句中,如:

    objectivec 复制代码
     String sql = "SELECT * FROM products WHERE name = '" + userInput + "'";
    • 攻击者输入:' OR 1=1 --,导致查询所有产品。
    SQL注入解决方式
预编译方式

把SQL语句中的参数使用?占位符来表示,先把SQL语句编译,格式固定的,再给?传入值,传入任何内容都表示值,数据库会判断SQL执行的结果。

objectivec 复制代码
 //获取到连接
 Onnection coon = DriverManner.geetConnection()
     //使用?占位符
     String sql = "select * from user where username = ? and password = ?"
 //预编译SQL语句,把SQL语句固定  
 PrepareStatement stmt = connection.prepareStatement(sql)
  //需要给?设置值,传入的值是什么类型就是setxxx,第一个参数是第几个问号,第二个参数是传入的值
     stmt.setString(index,result)  
复制代码
 

事务

概述
  • 事务是数据库提供的一个特性

  • 组成各个数据的执行的单元,要么都成功,要么都不成功。

在JDBC中操作事务

1.操作事务,需要掌握的是Connection接口,提供了方法

  • void setAutoCommit(boolean autoCommit) -- 如果传入了false,设置mysql数据库的事务不默认提交。

  • void commit() -- 提交事务

  • void rollback() --回滚事务

2.Connection接口的2个作用

  • 操作数据库,都需要使用Connection接口

  • 管理事务

objectivec 复制代码
 connection coon = null;
 //预编译执行SQL语句对象
 preparedStatement stmt =null;
 tyr{
     //获取到连接
 coon = DriverManner.getConnection();
 //使用?占位符
 Sting sql =  " update user set money = money + ? where username = ?"
     //预编译SQL语句,把SQL语句固定
     stmt = coon.preparedStatment(sql)
     //开启事务,设置事务不自动提交,西药手动提交
     coon.setAutoCommit(false)
     //需要给?设值
     stmt.setDouble(1,-1000)
     stmt.setDouble(2,冠希)
     //长记性SQL语句,给冠希扣除1000元
     stmt.executUpdate()
     //--------------------------------------
     int a = 10 / 0
        stmt.setDouble(1,-000)
     stmt.setDouble(2,美美)
     stmt.executUpdate()
     //提交事务
     coon.commit()
 } catch(exception e){
     //回滚事务
     coon.rollback()
 }
复制代码
     
事务的特性

原子性:原子性对应的英文是Atomicity,即表示事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败;

一致性:一致性对应的英文是Consistency,事务执行后,数据库状态与其它业务规则保持一致。例如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的;

隔离性:隔离性对应的英文是Isolation,是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰;

持久性:持久性对应的英文是Durability,指的是一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须得保证通过某种机制恢复数据。

  1. 事务的特性

    • 原子性 -- 强调的是事务的不可分割的特性

    • 一致性 -- 强调的是事务执行前后数据需要保证一致

    • 隔离性 -- 强调的是多个事务同时操作一条记录,事务之间不能互相干扰

    • 持久性 -- 强调的是事务一旦结束了,数据将永久的保存到数据库中

  2. 这些特性都是数据库提供的

不考虑事务的隔离性会引发的问题
  1. 脏读:一个事务读取到了另一个事务尚未提交的数据。(事务 A 修改数据但未提交,事务 B 读取了该数据,随后事务 A 回滚,导致事务 B 读取到无效数据。)

  2. 不可重复读:一个事务读取到了另一个事务已提交的更新数据,致使同一事务内多次查询结果不一致,侧重于数据更新(update)导致的问题。(事务 A 第一次读取数据,事务 B 修改并提交该数据,事务 A 再次读取时发现数据变化。)

  3. 虚读(幻读):一个事务读取到了另一个事务已提交的新插入数据,造成同一事务内多次查询结果不一致,强调的是插入(insert)操作向表中添加数据所引发的问题。(事务 A 查询某条件的数据,事务 B 插入符合该条件的新数据并提交,事务 A 再次查询时发现多了一条记录。)

设置事务的隔离级别

解决上述各种读的问题,设置数据库的隔离级别

  1. 事务的隔离级别(通过设置数据库的隔离级别,依据级别差异解决上述读取问题)

    • Read uncommitted -- 无法解决任何问题

    • Read committed -- 可避免脏读,但不可重复读和虚读有可能出现

    • Repeatable read -- 能避免脏读和不可重复读,虚读仍有产生的可能

    • Serializable -- 可避免脏读、不可重复读和虚读等各种读取问题

  2. 4种隔离级别在安全性和效率方面的表现

    • 安全:Serializable > Repeatable read > Read committed > Read uncommitted

    • 效率:Serializable < Repeatable read < Read committed < Read uncommitted

  3. 数据库均有自身默认的隔离级别

    • MySQL数据库,默认的隔离级别是Repeatable read,可避免脏读和不可重复读。
演示脏读
  1. 脏读:一个事务读取到了另一个事务未提交的数据。

  2. 进行测试

    • 开启两个窗口,一个为A窗口(左),一个为B窗口(右)。

    • 在A窗口中,查询A窗口的隔离级别:select @@tx_isolation;

    • 设置A窗口的隔离级别为最低级别:set session transaction isolation level read uncommitted;

    • 在两个窗口中,都开启事务:start transaction;

    • 在B窗口中完成转账操作(冠希给美美转1000元):

      • update t_account set money = money - 1000 where username = '冠希';

      • update t_account set money = money + 1000 where username = '美美';

    • 注意:B窗口的事务未提交。

    • 在A窗口中,查询美美的结果:select * from t_account;

    • 在B窗口中,回滚事务:rollback;

避免脏读:

  1. 避免脏读的发生,提高隔离级别。

    • set session transaction isolation level read committed;
  2. 在两个窗口中,都开启事务:start transaction;

  3. 在B窗口中完成转账操作(冠希给美美转1000元):

    • update t_account set money = money - 1000 where username = '冠希';

    • update t_account set money = money + 1000 where username = '美美';

    • 注意:此时事务尚未提交,需观察A窗口能否读取到B创建但未提交的数据。

  4. 在A窗口中,查询美美的结果:select * from t_account;

  5. 在B窗口中提交事务:commit;

  6. 在A窗口中,再次查询:两次查询结果不一致,发生了不可重复读。

数据库连接池

概述
1. 总结

原先在程序运行过程中,需自行创建连接与销毁连接,这一过程较为耗费时间和资源。如今引入连接池,预先创建好部分连接,程序可从连接池中获取连接,使用完毕后归还至连接池。这种方式节省了创建与释放连接的时间,降低了性能消耗,同时连接池中的连接可起到复用作用,有效提升了程序性能。

2. 连接池(池参数,若不指定,有默认值)
  • 初始大小:10个

  • 最小空闲连接数:3个

  • 增量:一次创建的最小单位(5个)

  • 最大空闲连接数:12个

  • 最大连接数:20个

  • 最大的等待时间:1000毫秒

3. 4个参数

对于任何开源的连接池,以下4大参数均需自行设置:

  • 驱动的名称:-- com.mysql.jdbc.Driver

  • 连接:-- jdbc:mysql:///day14

  • 用户名:-- root

  • 密码:-- root

druid连接池

DataSource接口概述
  1. DataSource接口性质:DataSource接口是由SUN公司提供的接口,任何开源的连接池或是自定义的连接池都必须要实现该接口。

  2. DataSource接口方法

    • 方法签名Connection getConnection()

    • 方法作用 :开源的连接池已经实现了DataSource接口,通过调用getConnection()方法就能够从连接池中获取到数据库连接。

  3. 连接池

    • 初始化连接:在创建连接池的时候,会预先初始化好一些数据库连接。

    • 连接归还:当程序使用完获取的连接后,需要将连接归还到连接池中。

常见的连接池
  1. DBCP连接池

  2. C3P0连接池

  3. DRUID连接池

    • 概述:Druid首先是一个数据库连接池。它是目前表现极为出色的数据库连接池,在功能、性能以及扩展性方面,均超越其他数据库连接池,如DBCP、C3P0、BoneCP、Proxool、JBoss DataSource等。Druid在阿里巴巴已经部署了超过600个应用,并且历经一年多生产环境大规模部署的严峻考验。

    • 功能

      • 替代功能:能够替换DBCP和C3P0。Druid提供了一个高效、功能强大且可扩展性良好的数据库连接池。

      • 性能监控:具备数据库访问性能监控功能。Druid内置了功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能很有帮助。

      • 密码加密:支持数据库密码加密。直接将数据库密码写在配置文件中是不安全的行为,容易导致安全问题,而Druid的DruidDriver和DruidDataSource都支持PasswordCallback。

      • 日志监控:提供SQL执行日志功能。Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,用户可以按需选择相应的LogFilter,以监控应用的数据库访问情况。

使用:

1.导入开发的jar包druid-1.1.10 jar

2.编写测试程序

objectivec 复制代码
 //创建连接池对象,从连接池中获取到连接对象
 DriudDataSource dataSouce = new DruidScouce();
 //设置4个参数  驱动类  地址  用户名  密码
 dataSource.setDriverClassName("com.mysql.jdbc.Driver");
 dataSource.setUrl("jdbc:mysql:///jva_web");
 dataSuorce.setUserName("root");
 dataSource.setPassword("root");
 //设置初始化连接个数,默认是0
 dataSource.setInitialSize(5);
 //设置最大连接数
 dataSuource.setMaxActive(10)
     //最大等待时间,单位是毫秒,
     dataSource.setMaxWait(2000)
     //   -----------连接池创建完成  
     //定义连接对象
     Connection coon = null;
 PreparedStatemtne stmt = null;
     //获取到连接对象
        coon =  dataSource.getConnection()
        //编写SQL语句
            String sql = "insert into user values(null,?,?,?)"
           //预编译SQL语句
            stmt = coon.prepareStatement(sql)
            //设置值
            stmt.setString(1,"eee");
            stmt.setString(2,"lll");
             stmt.setString(3,666);
 //执行sql
 stmt.executUpdate();
 //释放资源
 if(stmt != null) {
     stmt.close();
 }
 if(coon != null) {
     //把coon关闭了,其实连接池的底层已经对close()方法进行增强,以前是销毁连接,现在是归还连接
     coon.close();     
 }
复制代码

3.使用配置文件的方式

objectivec 复制代码
 写一个配置文件
 driverClassName=com.mysql.jdbc.Driver
 url=jdbc:mysql://jaba-web
 username=root
 password=root
 initialSize=5
 maxActive=10
 maxWait=3000
 maxIdle=6
 minIdle=3
 //加载属性文件,使用工厂对象创建连接池对象
 properties pro = new Properties();
 //加载属性文件
  InputStream  inputStream  = Test.class.getResourceAsStream("配置文件的路径");
      pro.load(inputStream)
      //创建连接池对象
      DataSource dataSource = DruidDataSourceFactory.createDataSource(pro)
      //获取连接,预编译SQL语句
      dataSource.getContention();
复制代码
      
相关推荐
程序员云帆哥3 天前
MySQL JDBC Driver URL参数配置规范
数据库·mysql·jdbc
Predestination王瀞潞7 天前
Java EE开发技术(Servlet整合JDBC银行管理系统-上)
java·servlet·java-ee·jdbc
李贺梖梖12 天前
JDBC初识
jdbc
程序员三明治13 天前
【MyBatis从入门到入土】告别JDBC原始时代:零基础MyBatis极速上手指南
数据库·mysql·mybatis·jdbc·数据持久化·数据
猿事如此1 个月前
12-人事管理系统
mysql·servlet·jdbc·c3p0
励志成为糕手2 个月前
企业级Spring事务管理:从单体应用到微服务分布式事务完整方案
分布式·spring·微服务·隔离级别·事务管理
Savvy..3 个月前
Day07 JDBC+MyBatis
mybatis·jdbc·数据库连接池·sql注入·yml
zhangyifang_0093 个月前
SpringJDBC源码初探-JdbcTemplate类
spring·jdbc
Brookty4 个月前
【MySQL】JDBC编程
java·数据库·后端·学习·mysql·jdbc