文章目录

  • 1. 数据库编程的基础条件
  • 2. Java 的数据库编程:JDBC
  • 3. JDBC 访问数据库的层次结构
  • 4. MySQL 数据库操作介绍
  • 5. MySQL 驱动包的下载及添加到项目
  • 6. JDBC 使用步骤
    • 6.1 创建数据库源,连接 Connection
    • 6.2 构造 SQL 语句,为执行的操作做准备
    • 6.3 执行 SQL,并处理结果集
    • 6.4 释放资源
    • 6.5 JDBC 编程模板
  • 7. JDBC 常用接口和类
    • 7.1 DriverManager
    • 7.2 DataSource 和 MysqlDataSource
    • 7.3 Connection
    • 7.4 PreparedStatement
    • 7.5 ResultSet
  • 8. Java 操作数据库实例
    • 8.1 往表中新增数据
    • 8.2 删除表中的数据
    • 8.3 修改表中的数据
    • 8.4 查找表中的数据
  • 9. 数据库连接池
    • 9.1 数据库连接池介绍
    • 9.2 数据库连接池实现
    • 9.3 Druid 使用步骤

1. 数据库编程的基础条件

如果你想实现代码操作数据库,那么以下条件是你实现它的前提

  1. 编程语言

    例如 Java、C++、Python 等等,这些语言都能够实现操作数据库

  2. 某个数据库的操作

    例如我在前面章节就介绍了关于 MySQL 的操作,实现其它数据库如 Oracle、SQL Server 等等也要学会对应数据库的一些操作

  3. 安装数据库驱动包

    不同的数据库对应不同的编程语言提供了不同的数据库驱动包,这些驱动包内实现了操作对应数据库的 API

2. Java 的数据库编程:JDBC

由于不同数据库的厂商实现数据库的 API 其实是不太一样的,因此很多语言就把这些数据库的 API 进行再一次的封装,封装出了一套统一的 API。这样就可以通过一套代码来操作多个不同的数据库了

在 Java 中,这样的封装就是由 Java 标准库来完成的,封装出了一套统一的数据库 API 称为 JDBC

拓展:

Java 本身是跨平台语言,虽然不同操作系统提供了不同的 API,但是 Java 本身也把这些 API 封装了起来,在标准库中提供了统一的接口,因此 Java 就可以一次编译,到处运行

JDBC 介绍:

  • JDBC,即 Java Database Connectivity,是指 Java 数据库连接。是一种用于执行 SQL 语句的 Java API,它是 Java 中的数据库连接规范。
  • 这个 API 由 java.sqljavax.sql 包中的一些类和接口组成,它为 Java 开发人员操作数据库提供了一个标准的 API,可以为多种关系数据库提供统一访问

注意:

  • JDBC API 是 Java 标准库自带的,可以直接用,但是 MySQL 的 JDBC 驱动不是系统自带的,因此需要额外进行下载安装
  • MySQL 的 JDBC 驱动其实就是对 JDBC API 里面一些类和接口的具体实现

3. JDBC 访问数据库的层次结构

4. MySQL 数据库操作介绍

在前面章节我就介绍了关于 MySQL 的一些知识了,如果你在这方面有漏洞的话,可以直接通过下面的文章来进行补充。

第一章链接:【MySQL 数据库】数据库的基础知识

第二章链接:【MySQL 数据库】MySQL 的对库的操作及其数据类型

第三章链接:【MySQL 数据库】数据表的基本操作

第四章链接:【MySQL 数据库】数据库的约束及数据表的设计思想

第五章链接:【MySQL 数据库】聚合查询和联合查询操作

第六章链接:【MySQL 数据库】MySQL 的索引和事务

5. MySQL 驱动包的下载及添加到项目

由于 MySQL 的 JDBC 驱动不是系统自带的,因此需要额外进行下载安装

各大数据库的官网就有对应数据库的 JDBC 驱动,但这里我推荐使用一些中央仓库来进行下载,例如 mvnrepository

驱动包下载步骤:

  1. 进入 mvnrepository 网站,在搜索栏搜索 MySQL,就可以查询到以下结果
  2. 选择第一个 MySQL Connector/J,就可以跳转到下载版本选择的页面
  3. 选择好自己对应的数据库版本的驱动(大版本一定要对应,小版本区别不大可以随意选),由于我自己是 5.x 系列的 MySQL,因此,我选择大版号是5的就行。选择后就跳到了最终下载的页面
  4. 点击 jar 就开始下载了(这个 jar 包就是将这个驱动包中的一些 .class 文件以压缩包的形式进行打包了)
  5. 下载完成后,这个驱动包就已经下载到你本地了,只再将它引入到你的项目就可以是用了

驱动包添加到项目步骤(以下介绍一种方法):

  1. 首先用自己的编译器创建一个项目(我个人用的 IDEA,但是其它编译器方式也一样)
  2. 在你的项目里面新建一个目录,目录名随意(我个人起的是 lib)
  3. 将下载的驱动包添加到这个目录中,直接 CV 就行,添加成功后就会出现
  4. 让我们新建的这个添加了驱动包的目录成为一个库(IDEA 中右键该目录,选择 add as Library… 就可以)
  5. 将这个库加好之后,就可以使用驱动包中的类和方法了,此时就可以进行数据库编程了

6. JDBC 使用步骤

6.1 创建数据库源,连接 Connection

  1. 创建一个数据库源

    DataSource dataSource=new MysqlDataSource();// DataSource 是来自于 Java 标准库的一个接口,它用来表示“数据库在哪”// MysqlDataSource 是来自于 MySQL 的驱动包,它是实现了 DataSource 接口的类

    数据库就是一个服务器程序,可以通过 DataSource 来描述服务器的 地址、端口、用户名、密码、要访问的数据库名等

  2. 把数据库的位置信息,设置到 DataSource 中

    // 1)通过一个 URL 来表示连接的数据库、数据库的 ip、端口、数据库名、编码方式、是否加密((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&setSSL=false");// 2)设置登录数据库的用户名((MysqlDataSource)dataSource).setUser("root");// 3)设置登录数据库的密码((MysqlDataSource)dataSource).setPassword("1234");
    • 由于 setURL、setUser、setPassword 都是 MysqlDataSource 实现的,所以使用时需要向下转型
    • 上述 URL 是一种固定的写法,例如:jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&setSSL=false
      • jdbc 表示使用 JDBC 访问数据库
      • mysql 表示访问的数据库是 MySQL
      • 172.0.0.1 是 IP 地址,IP 地址是用来区分是哪个主机,172.0.0.1 这个 IP 地址表示当前使用的主机自身,因为我的 MySQL 服务器也装在自己电脑上,自行修改
      • 3306 是端口号,这是安装数据库服务器时手动设置的,一般默认是3306,它是用来区分主机上的某个程序
      • test 是要访问的数据库名,这是我数据库里面的,自行修改
      • characterEncoding=utf8 是用来指定编码方式的,此处是使用 utf8,需要和使用的数据库便方式对应,自行修改
      • useSSL=false 是用来表示是否加密的,此处表示不加密,自行修改
  3. 连接数据库,进行真正的网络通信

    Connection connection=dataSource.getConnection();
    • Connection 是 Java 标准库里的,虽然 MySQL 驱动里面也有。它是用来进行和数据库服务器进行网络连接的
    • getConnection 用于获得试图建立到指定数据库 URL 的连接,如果连接成功就返回一个 Connection 对象,如果失败就抛出异常
    • 由于 getConnection 可能会连接失败(例如 IP 地址、端口等输入错误),因此就需要在方法声明时通过 throws 给上层调用者抛出异常或者使用 try-catch 去处理异常

6.2 构造 SQL 语句,为执行的操作做准备

  1. 通过字符串,构造一个要执行的 sql

    // 例如要执行新增元素操作(表名为 student,有两列 id 和 studentScanner scanner=new Scanner(System.in);System.out.print("请输入 id:");int id=scanner.nextInt();System.out.print("请输入 姓名:");String name=scanner.next();String sql="insert into student values(?,?)";
    • sql 就是构造的 SQL 语句,里面就是要执行的具体操作
    • sql 语句中可以不用加分号
    • ?表示通配符,可以通过它对 sql 语句里的内容进行动态替换,需要替换的内容用 ?代替,后续再使用 PreparedStatement 对象的一些方法将其再替换成具体要更改的值,例如:
      • void setInt(int paramenterIndex, int x) :paramenterIndex 表示 sql 语句中要替换通配符的具体位置(从1开始),x 表示要替换掉具体值
      • void setString(int parameterIndex, String x) :paramenterIndex 表示 sql 语句中要替换通配符的具体位置(从1开始),x 表示要替换掉具体值
  2. 通过 prepareStatement(sql) 方法,将构造的字符串 sql 转化成真正的数据库底层的 SQL 语句

    PreparedStatement statement=connection.prepareStatement(sql);// 通过 setInt 方法,将 SQL 语句中的第一处通配符进行具体值的替换statement.setInt(1,id);// 通过 setString 方法,将 SQL 语句中的第二处通配符进行具体值的替换statement.setString(2,name);

    JDBC 中,使用 Connection 和数据库建立了连接对象 connection,那么 connection 就可以调用 prepareStatement(String sql) 方法对参数 sql 指定的 SQL 语句进行编译预处理,生成该数据库底层的内部命令,并将该命令封装在 PreparedStatement 对象中

6.3 执行 SQL,并处理结果集

通过 PreparedStatement 对象的 executeQuery 或者 executeUpdate 方法来执行 SQL

  • 如果是执行内容变更的操作(增加、修改、删除),就使用 int executeUpdate() 方法

    int ret=statement.executeUpdate();// executeUpdate 的返回结果是执行该操作后影响的行数// 可以通过打印返回值来显示影响的行数System.out.println("ret: "+ret);
  • 如果要是要执行查询操作,就使用 ResultSet executeQuery() 方法

    ResultSet resultSet=statement.executeQuery();// executeQuery 的返回结果是执行该操作后查询到的类似于临时表的结构,存放在 ResultSet 对象中// 接下来我们可以对它进行遍历,类似于迭代器的遍历,方法如下while(resultSet.next()){// 假设有两列 id 和 nameint id=resultSet.getInt(id);String name=resultSet.getString(name);System.out.println("id="+id+", name="+name);}
    • SQL 查询语句对数据库的查询操作将返回一个 ResultSet 对象,ResultSet 对象由按列(字段)组织的数据行构成
    • ResultSet 对象一次只能看到一行数据,使用 next() 方法,可以移到下一个数据行(类似于 i++)
    • 可以使用 ResultSet 对象的 getXxx() 方法,去获得字段。常用方法后面讲将介绍

6.4 释放资源

当我们执行完了我们的 SQL 语句后,如果不再使用某些对象,就需要把连接关闭,释放掉对应的资源

// 如果有 ResultSet 对象不需要使用后,需要关闭这个连接resultSet.close();// Connection 不需要使用后,需要关闭这个连接connection.close();// PreparedStatement 不需要使用后,需要关闭这个连接statement.close();
  • ResultSet、Connection、PreparedStatement 这些对象都对应着一些及机器的硬件资源,如果不使用的话就要及时还回去。就类似于借书,如果大家在图书馆只借书,不还书,那么图书馆的书籍资源就会一直减少
  • 这些对象可以使用 close() 方法,来关闭和客户端与服务器建立的连接,以此释放占用的资源

6.5 JDBC 编程模板

通过上面五步,就可以进行基础的 Java 的 JDBC 编程了,虽然方法不止这一种,但如果你还不会的话,掌握这个方法就行了。最后再总结下整个的模板,依据它,我们就可以用 Java 语言对 MySQL 数据库进行各种操作

public static void test(){// 1. 创建数据库源,连接 ConnectionDataSource dataSource=new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");Connection connection=dataSource.getConnection();// 2. 构造一个 SQL 语句,为要进行的操作做准备String sql="";PreparedStatement statement=connection.prepareStatement(sql);// 3. 执行 SQL,并处理结果集int ret=statement.executeUpdate();// 4. 执行完成,释放资源statement.close();connection.close();}

7. JDBC 常用接口和类

上述 JDBC 编程步骤中已经将以下接口和类介绍了很多,所以可以互相补充漏洞

7.1 DriverManager

DriverManager 是一个工具类,可以进行注册驱动和获取数据库连接。

  • 注册驱动是通过反射先将 com.mysql.jdbc.Driver 加载到内同存中,然后这个 Driver 类内部有一个静态代码块,当 Driver 类加载到内存中时,DriverManager 会对它进行注册。

    在 MySQL5 之后,不需要再添加反射的这段代码,因为 MySQL jar 包的 META-INF/services/java.sql.Driver 文件中记录了 Driver 类的全路径名。会通过这个自动进行加载。

7.2 DataSource 和 MysqlDataSource

补充:

上述代码也可以直接使用 MysqlDataSource 来创建一个数据源,这样就可以不用使用向下转型了。但是如果使用 DataSource 的话,那么代码中其它代码其实都是使用 DataSource 这个类型的,这是和具体数据库类型无关的类,当你需要切换数据库时,就不需要大幅度修改代码

7.3 Connection

Connection 接口实现类由数据库提供,它能够获取执行 SQL 的对象和管理事务。
获取 Connection 对象通常有两种方式:

  • 方式一: 通过 DataSource(数据源)对象获取

    // 创建一个数据库源DataSource dataSource=new MysqlDataSource();// 设置数据库具体信息((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test" />);((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");// 创建数据库连接Connection connection=dataSource.getConnection();
  • 方式二: 通过 DriverManager(驱动管理类)的静态方法获取(通过反射将数据库的的驱动类加载到内存中)

    // 加载 JDBC 驱动程序Class.forName("com.mysql.cj.jdbc.Driver");// 创建数据库连接Connection connection=DriverManager.getConnection(url, username, password);

    MySQL 数据库驱动程序被封装在 Driver 类中,该类的包名是 com.mysql.cj.jdbc,该类不是 Java 运行环境类库中的类

  • 上述两种方式的区别:

    • DriverManager 类来获取的 Connection 连接,是无法重复利用的,每次使用完以后释放资源时,通过 connection.close() 都是关闭物理连接
    • DataSource 提供连接池的支持。连接池在初始化时创建一定数量的数据库连接,这些连接是可以重复利用的,每次使用完数据库连接,通过 connection.close() 释放资源,都是将 Connection 连接对象回收

当创建好数据库连接对象后,可以通过 Connection 类的 createStatement()prepareStatement() 方法去创建 PreparedStatement 对象。这两种方法的区别如下:

createStatement()prepareStatement()
概念上会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。不会初始化,没有预处理,每次都是从0开始执行SQL。
变量上可以在SQL中通过?进行变量替换不可以在SQL中通过?进行变量替换,只能进行字符串拼接

JDBC 的事务管理是通过 Connection 接口中定义的3个方法执行的:

  • 开启事务:setAutoCommoit(boolean autoCommit)(true 为自动提交事务;false 为手动提交事务,即开启事务)
  • 提交事务:commit()
  • 回滚事务:rollback()

7.4 PreparedStatement

PreparedStatement 是 JDBC API 提供的三种可以将 SQL 语句发送到数据库的对象之一。这里对这三种做一个简单介绍

  • Statement: 用于执行不带参数的简单 SQL
  • PreparedStatement:
    • 用于执行带或者不带参数的 SQL 语句
    • SQL 语句会预编译在数据库系统
    • 执行速度快于 Statement 对象
  • CallableStatement: 用于执行数据库存储过程的调用

PreparedStatement 继承了 Statement,它能够预编译 SQL 语句并执行,预防了SQL 注入问题(将占位符替换值中的敏感字符进行转义)。

SQL 注入是通过操作输入来修改事先定义好的 SQL 语句,用以达到执行代码对服务器进行攻击的方法。

PreparedStatement 原理:

  1. 在获取 PreparedStatement 对象时,将 sql 语句发送给 mysql 服务器进行检查、编译(这些步骤比较耗时)。
  2. 执行 sql 时就不用进行以上步骤,直接替换占位符的值即可,速度更快。
  3. 并且当 sql 模板一样时,只需要进行一次检查、编译。

注意:

PreparedStatement 的预编译功能默认是关闭的,开启的方式为:在 url 后面加上 useServerPrepStmts=true

7.5 ResultSet

  • ResultSet 对象它被称为结果集,它代表符合 SQL 语句条件的所有行,并且它通过一套 getXxx() 方法提供了对这些行中数据的访问
  • ResultSet 里的数据是一行一行排列的,每当有多个字段,并且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用 ResultSet 的 next() 方法,可以通过结合 while 循环来遍历 ResultSet 里的所有记录

常见 ResultSet 对象方法:

方法说明
int getInt(String columnName)返回该行对应列名的值
String getInt(String columnName)返回该行对应列名的值
Date getInt(String columnName)返回该行对应列名的值
double getInt(String columnName)返回该行对应列名的值
int getInt(int columnIndex)返回改行对应列的位置的值
String getInt(int columnIndex)返回改行对应列的位置的值

注意:

ResultSet 对象和数据库连接对象 Connection 实现了紧密连接,一旦连接对象被关闭,ResultSet 对象中的数据就会立刻消失

8. Java 操作数据库实例

8.1 往表中新增数据

在 student 表中新增学生 id 和 name

public static void testInsert() throws SQLException {DataSource dataSource=new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");Connection connection=dataSource.getConnection();Scanner scanner=new Scanner(System.in);System.out.print("请输入id:");int id=scanner.nextInt();System.out.print("请输入姓名:");String name=scanner.next();String sql="insert into student values(?,?)";PreparedStatement statement=connection.prepareStatement(sql);statement.setInt(1,id);statement.setString(2,name);int ret=statement.executeUpdate();System.out.println("ret: "+ret);statement.close();connection.close();}

8.2 删除表中的数据

在表名为 student 的表中,删除学生表中符合 id 条件的记录

public static void testDelete() throws SQLException {DataSource dataSource=new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");Connection connection=dataSource.getConnection();Scanner scanner=new Scanner(System.in);System.out.print("请输入要删除的 id:");int id=scanner.nextInt();String sql="delete from student where id=?";PreparedStatement statement=connection.prepareStatement(sql);statement.setInt(1,id);int ret=statement.executeUpdate();System.out.println("ret: "+ret);statement.close();connection.close();}

8.3 修改表中的数据

在表名为 student 的表中,将符合 id 条件的学生姓名进行修改

public static void testUpdate() throws SQLException {DataSource dataSource=new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");Connection connection=dataSource.getConnection();Scanner scanner=new Scanner(System.in);System.out.print("情输入你要更改的学生 id:");int id=scanner.nextInt();System.out.print("请输入你要更改后的学生姓名:");String name=scanner.next();String sql="update student set name=? where id=?";PreparedStatement statement=connection.prepareStatement(sql);statement.setString(1,name);statement.setInt(2,id);int ret=statement.executeUpdate();System.out.println("ret: "+ret);statement.close();connection.close();}

8.4 查找表中的数据

查找表名为 student 的表中的所有数据

public static void testSelect() throws SQLException {DataSource dataSource=new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1234");Connection connection=dataSource.getConnection();String sql="select * from student";PreparedStatement statement=connection.prepareStatement(sql);ResultSet resultSet=statement.executeQuery();while(resultSet.next()){int id=resultSet.getInt("id");String name=resultSet.getString("name");System.out.println("id = "+id+", name = "+name);}resultSet.close();statement.close();connection.close();}

9. 数据库连接池

9.1 数据库连接池介绍

  • 数据库连接池是个容器,负责分配、管理数据库连接(Connection)。
  • 它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
  • 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。

优点:

  • 资源重用
  • 提升系统响应速度
  • 避免数据库连接遗漏(当当前数据库连接池无空闲连接时,会判断已被使用的连接是否在使用中,如果没有被使用则会强制断开)

9.2 数据库连接池实现

官方(SUN公司)提供了数据库连接池的标准接口 DataSource,第三方组织可以实现此接口来实现各自的数据库连接池。其中通过继承 DataSource 中的 Connection getConnection() 方法就能够获取连接。
常见的数据库连接池有:

  • Druid
  • DBCP
  • C3P0

9.3 Druid 使用步骤

Druid 是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL 等 DB 池的优点,同时加入了日志监控,可以很好的监控 DB 池连接和 SQL 的执行情况,可以说是针对监控而生的 DB 连接池。
Druid 使用步骤如下:

  1. 导入 durid jar 包或引入 druid 依赖(durid jar 包下载地址如下:mvnrepository)

    <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency>
  2. 定义配置文件

  3. 加载配置文件

    Properties prop = new Properties();prop.load(new FileInputStream("配置文件路径"));
  4. 获取数据库连接池对象

    DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
  5. 获取连接

    Connection connection = dataSource.getConnection();

Druid 配置详解:

配置缺省值说明
name配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:“DataSource-” + System.identityHashCode(this)
jdbcUrl连接数据库的url,不同数据库不一样。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username连接数据库的用户名
password连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/%E4%BD%BF%E7%94%A8ConfigFilter
driverClassName根据url自动识别这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive8最大连接池数量
maxIdle8已经不再使用,配置了也没效果
minIdle最小连接池数量
maxWait获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatementsfalse是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
maxOpenPreparedStatements-1要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
timeBetweenEvictionRunsMillis有两个含义: 1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis
connectionInitSqls物理连接初始化的时候执行的sql
exceptionSorter根据dbType自动识别当数据库抛出一些不可恢复的异常时,抛弃连接
filters属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
proxyFilters类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系