Java(9):9.0 [过旧] Java JDBC-操作Mysql数据库

Java(9):9.0 [过旧] Java JDBC-操作Mysql数据库
Prorise第1章:JDBC概述
读前提醒:由于JDBC几乎没有人去直接使用,而是使用封装好的Mybatis或是其他的ORM框架,这个笔记也是和网络编程一样,早期写的,个人建议直接学习Mybatis即可,如果不想落下这一章或者对Sql还是不太熟悉的可以继续阅读这章节的笔记
1.1 数据的持久化
持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。
持久化的主要应用是将``内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。
1.2 Java中的数据存储技术
在Java中,数据库存取技术可分为如下几类:
JDBC直接访问数据库
JDO (Java Data Object )技术
第三方O/R工具,如Hibernate, Mybatis 等
JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
1.3 JDBC介绍
- JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
- JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
- JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
- 如果没有JDBC,那么Java程序访问数据库时是这样的:
- 有了JDBC,Java程序访问数据库时是这样的:
- 总结如下:
1.4 JDBC体系结构
- JDBC接口(API)包括两个层次:
- 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
- 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。
不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。 ————面向接口编程
1.5 JDBC程序编写步骤
补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。
第2章:获取数据库连接
2.1 要素一:Driver接口实现类
2.1.1 Driver接口介绍
java.sql.Driver
接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(
java.sql.DriverManager
)去调用这些Driver实现。- Oracle的驱动:oracle.jdbc.driver.OracleDriver
- mySql的驱动: com.mysql.jdbc.Driver
- 将上述jar包拷贝到Java工程的一个目录中,习惯上新建一个lib文件夹。
注意:如果是Dynamic Web Project(动态的web项目)话,则是把驱动jar放到WebContent(有的开发工具叫WebRoot)目录中的WEB-INF目录中的lib目录下即可
2.1.2 加载与注册JDBC驱动
加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名
- Class.forName(“com.mysql.jdbc.Driver”);
注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序
使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动
通常不用显式调用 DriverManager 类的 registerDriver() 方法来注册驱动程序类的实例,因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用
DriverManager.registerDriver()
方法来注册自身的一个实例。下图是MySQL的Driver实现类的源码:
2.2 要素二:URL
JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
JDBC URL的标准由三部分组成,各部分间用冒号分隔。
- jdbc:子协议:子名称
- 协议:JDBC URL中的协议总是jdbc
- 子协议:子协议用于标识一个数据库驱动程序
- 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
举例:
几种常用数据库的 JDBC URL
MySQL的连接URL编写方式:
- jdbc:mysql://localhost:3306/test
- jdbc:mysql://localhost:3306/test**?useUnicode=true&characterEncoding=utf8**(如果JDBC程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集)
- jdbc:mysql://localhost:3306/test?user=root&password=123456
Oracle 9i的连接URL编写方式:
- jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称
- jdbc:oracle:thin:@localhost:1521:test
- jdbc:oracle:thin:@主机名称:oracle服务端口号:数据库名称
SQLServer的连接URL编写方式:
jdbc:sqlserver://主机名称:sqlserver服务端口号:DatabaseName=数据库名称
jdbc:sqlserver://localhost:1433:DatabaseName=test
2.3 要素三:用户名和密码
- user,password可以用“属性名=属性值”方式告诉数据库
- 可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
2.4 数据库连接方式举例
2.4.1 连接方式一
1 | package chapter01; |
说明:上述代码中显式出现了第三方数据库的API
2.4.2 连接方式二
1 |
|
说明:相较于方式一,这里使用反射实例化Driver,不在代码中体现第三方数据库的API。体现了面向接口编程思想。
2.4.3 连接方式三
1 |
|
说明:使用DriverManager实现数据库的连接。体会获取连接必要的4个基本要素。
2.4.4 连接方式四
1 |
|
说明:不必显式的注册驱动了。因为在DriverManager的源码中已经存在静态代码块,实现了驱动的注册。
2.4.5 连接方式五(最终版)
1 |
|
其中,配置文件声明在工程的src目录的resource文件夹下:【jdbc.properties】
1 | user=root |
说明:使用配置文件的方式保存配置信息,在代码中加载配置文件
使用配置文件的好处:
①实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码
②如果修改了配置信息,省去重新编译的过程。
第3章:使用PreparedStatement实现CRUD操作
3.1 操作和访问数据库
数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。
在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:
- Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
- PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。
- CallableStatement:用于执行 SQL 存储过程
3.2 使用Statement操作数据表的弊端
通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。
Statement 接口中定义了下列方法用于执行 SQL 语句:
1
2int excuteUpdate(String sql):执行更新操作INSERT、UPDATE、DELETE
ResultSet executeQuery(String sql):执行查询操作SELECT但是使用Statement操作数据表存在弊端:
- 问题一:存在拼串操作,繁琐
- 问题二:存在SQL注入问题
SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令(如:SELECT user, password FROM user_table WHERE user=‘a’ OR 1 = ’ AND password = ’ OR ‘1’ = ‘1’) ,从而利用系统的 SQL 引擎完成恶意行为的做法。
对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement(从Statement扩展而来) 取代 Statement 就可以了。
代码演示:
1 | public class StatementTest { |
综上:
3.3 PreparedStatement的使用
3.3.1 PreparedStatement 介绍
获取方式
通过Connection
对象的preparedStatement(String sql)
方法获取PreparedStatement
对象。本质特性
- 是
Statement
接口的子接口 - 表示预编译过的 SQL 语句,执行效率更高
- 是
参数设置
- SQL 语句中的参数用
?
占位符表示 - 通过
setXxx(int parameterIndex, Xxx value)
方法设置参数:parameterIndex
: 参数索引(从 1 开始)value
: 参数值(类型需与 SQL 字段匹配)
- SQL 语句中的参数用
3.3.2 PreparedStatement vs Statement
对比维度 | PreparedStatement | Statement |
---|---|---|
可读性 | 支持参数化查询,SQL 与代码分离,可维护性更强 | SQL 拼接字符串,可读性差 |
性能 | 1. 预编译机制,DBServer 会缓存编译后的执行代码 2. 重复调用时直接替换参数,无需重新编译 | 每次执行需重新编译 SQL,性能较低 |
安全性 | 自动防止 SQL 注入攻击 | 直接拼接参数,存在 SQL 注入风险 |
性能优化原理
- 预编译机制:DBServer 对预编译语句的编译结果(语法检查、语义检查、二进制命令)进行缓存,后续调用时直接复用。
- Statement 缺点:即使 SQL 结构相同,因数据内容变化会被视为不同语句,无法利用缓存,每次需重新编译。
3.3.3 Java 与 SQL 数据类型转换表
Java 类型 | SQL 类型 |
---|---|
boolean | BIT |
byte | TINYINT |
short | SMALLINT |
int | INTEGER |
long | BIGINT |
String | CHAR , VARCHAR , LONGVARCHAR |
byte[] | BINARY , VARBINARY |
java.sql.Date | DATE |
java.sql.Time | TIME |
java.sql.Timestamp | TIMESTAMP |
关键总结
- 优先使用 PreparedStatement:提高性能、安全性和可维护性。
- 参数索引从 1 开始:调用
setXxx()
时需注意参数位置。 - 类型严格匹配:Java 类型与 SQL 类型的对应关系需准确。
3.3.4 使用PreparedStatement实现增、删、改操作
1 | package chapter01; |
3.3.5 使用PreparedStatement实现查询操作
1 | package chapter01; |
说明:使用PreparedStatement实现的查询操作可以替换Statement实现的查询操作,解决Statement拼串和SQL注入问题。
3.4 ResultSet与ResultSetMetaData
3.4.1 ResultSet
- 获取方式
通过PreparedStatement
的executeQuery()
方法执行查询,返回一个ResultSet
对象。 - 本质特性
- 以逻辑表格的形式封装查询结果集。
- 由数据库厂商提供实现。
- 初始时,指针指向第一条记录的前面。
- 游标操作
- 通过
next()
方法移动游标:- 检测下一行是否有效,若有效返回
true
并下移指针。 - 类似于
Iterator
的hasNext()
和next()
结合。
- 检测下一行是否有效,若有效返回
- 通过
getXxx(int index)
或getXxx(String columnName)
获取列值:- 例如:
getInt(1)
、getString("name")
。 - 注意:JDBC API 中的索引从 1 开始。
- 例如:
- 通过
- 常用方法
boolean next()
:移动游标到下一行。getString(int index)
/getString(String columnName)
:获取字符串类型值。- 其他类似方法:
getInt()
、getDouble()
等。
3.4.2 ResultSetMetaData
- 获取方式
通过ResultSet
的getMetaData()
方法获取ResultSetMetaData
对象。 - 核心功能
- 获取结果集的列信息(列名、别名、类型等)。
- 常用方法:
getColumnName(int column)
:获取指定列的名称。getColumnLabel(int column)
:获取指定列的别名。getColumnCount()
:返回结果集中的列数。getColumnTypeName(int column)
:获取指定列的数据库类型名称。getColumnDisplaySize(int column)
:获取指定列的最大显示宽度(字符数)。isNullable(int column)
:判断指定列是否允许NULL
值。isAutoIncrement(int column)
:判断指定列是否自增。
问题1:得到结果集后, 如何知道该结果集中有哪些列 ? 列名是什么?
需要使用一个描述 ResultSet 的对象, 即 ResultSetMetaData
问题2:关于ResultSetMetaData
- 如何获取 ResultSetMetaData: 调用 ResultSet 的 getMetaData() 方法即可
- 获取 ResultSet 中有多少列:调用 ResultSetMetaData 的 getColumnCount() 方法
- 获取 ResultSet 每一列的列的别名是什么:调用 ResultSetMetaData 的getColumnLabel() 方法
3.5 资源的释放
- 释放ResultSet, Statement,Connection。
- 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
- 可以在finally中关闭,保证及时其他代码出现异常,资源也一定能被关闭。
3.6 JDBC API小结
两种思想
面向接口编程的思想
ORM思想(object relational mapping)
- 一个数据表对应一个java类
- 表中的一条记录对应java类的一个对象
- 表中的一个字段对应java类的一个属性
sql是需要结合列名和表的属性名来写。注意起别名。
两种技术
- JDBC结果集的元数据:ResultSetMetaData
- 获取列数:getColumnCount()
- 获取列的别名:getColumnLabel()
- 通过反射,创建指定类的对象,获取指定的属性并赋值
- JDBC结果集的元数据:ResultSetMetaData
章节练习
练习题1:从控制台向数据库的表customers中插入一条数据,表结构如下:
1 | package chapter01; |
练习题2:创立数据库表 examstudent,表结构如下:
1 | // 创建考试表 |
向数据表中添加如下数据:
1 | package chapter01; |
第4章 操作BLOB类型字段
4.1 MySQL BLOB类型
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
- 实际使用中根据需要存入的数据大小定义不同的BLOB类型。
- 需要注意的是:如果存储的文件过大,数据库的性能会下降。
- 如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数: max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。
4.2 向数据表中插入大数据类型
1 | public static void testInsertBlob() throws Exception { |
4.3 修改数据表中的Blob类型字段
1 | // 修改blob的数据 |
4.4 从数据表中读取大数据类型
1 | // 读取blob数据 |
第5章 批量插入
5.1 批量执行SQL语句
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
- addBatch(String):添加需要批量处理的SQL语句或是参数;
- executeBatch():执行批量处理语句;
- clearBatch():清空缓存的数据
通常我们会遇到两种批量执行SQL语句的情况:
- 多条SQL语句的批量处理;
- 一个SQL语句的批量传参;
1 | package chapter01; |
5.2 高效的批量插入
举例:向数据表中插入20000条数据
- 数据库中提供一个goods表。创建如下:
1 | CREATE TABLE goods( |
5.2.1 实现层次一:使用Statement
1 | Connection conn = JDBCUtils.getConnection(); |
5.2.2 实现层次二:使用PreparedStatement
1 | long start = System.currentTimeMillis(); |
5.2.3 实现层次三
1 | /* |
5.2.4 实现层次四
1 | /* |
好的,下面是整理后的笔记内容,突出重点并添加相关的代码示例。
第6章:数据库事务
6.1 数据库事务介绍
事务 是一组逻辑操作单元,确保数据从一种状态变换到另一种状态。
事务处理:保证所有事务作为一个工作单元来执行,即使出现故障,事务也不能被中断。事务中的多个操作要么全部提交(commit),要么全部回滚(rollback)。
- 提交(commit):当事务中的所有操作成功时,所有修改永久保存到数据库中。
- 回滚(rollback):如果事务中的某个操作失败,所有修改会被撤销,回到事务开始前的状态。
为确保数据一致性,事务中的操作必须被当做一个整体来执行,只有在所有操作成功时,数据的一致性才会得到保持。
6.2 JDBC事务处理
自动提交与手动提交:
- 默认自动提交:当连接创建时,事务会自动提交,每执行一次 SQL 语句,都会自动提交。
- 关闭数据库连接:如果连接关闭,事务会自动提交。
- 手动提交事务:使用
setAutoCommit(false);
来关闭自动提交,事务的提交和回滚由程序控制。
JDBC事务管理步骤:
- 取消自动提交:
conn.setAutoCommit(false);
- 执行所有 SQL 语句。
- 如果没有异常,提交事务:
conn.commit();
- 如果有异常,回滚事务:
conn.rollback();
- 取消自动提交:
案例:用户AA向用户BB转账100
1 | package chapter01; |
第7章:DAO及相关实现类
1. 什么是DAO?
- DAO:封装数据访问操作的对象,提供统一接口进行 CRUD(创建、读取、更新、删除) 操作。
- 作用:解耦业务逻辑和数据库操作,提高代码维护性。
目录结构
1 | src |
1. 数据模型层(User.java
)
1 | package com.Prorise.DAO.model; |
2. DAO 接口(UserDao.java
)
1 | package com.Prorise.DAO.dao; |
3. DAO 实现类(UserDaoImpl.java
)
1 | package com.Prorise.DAO.dao; |
4. 服务层(UserService.java
)
1 | package com.companyname.projectname.service; |
5. JDBC 工具类(JDBCUtils.java
)
1 | package com.Prorise.DAO.util; |
6. 测试类(UserServiceTest.java
)
1 | package com.Prorise.DAO.test; |
第8章:数据库连接池
8.1 为什么需要数据库连接池?
传统的 JDBC 数据库连接方式:
- 每次建立数据库连接(DriverManager 获取 Connection)。
- 执行 SQL 操作(增删改查)。
- 断开数据库连接(关闭 Connection)。
传统方式存在的问题
❌ 连接创建 & 关闭成本高:每次连接都需要验证用户名和密码,建立连接时间 0.05s~1s,影响性能。
❌ 无法复用数据库连接:每个请求都新建连接,导致数据库连接资源浪费。
❌ 连接数不受控制:当并发用户增多(几百/几千人在线),大量连接可能会导致服务器崩溃。
❌ 容易导致内存泄漏:如果异常导致连接未关闭,可能会耗尽数据库资源。
8.2 什么是数据库连接池?
数据库连接池(Connection Pool) 通过 “缓存数据库连接” 来优化数据库连接的管理,避免频繁创建和关闭连接的开销。
工作流程
- 应用程序启动时,数据库连接池创建一组连接(最小连接数)。
- 应用程序请求数据库连接,从连接池获取可用连接。
- 使用完数据库连接后,不直接关闭,而是归还给连接池,以便重复利用。
- 当请求连接数超过最大连接数时,新的请求会等待,避免连接过载。
8.3 数据库连接池的优点
✅ 减少资源消耗:避免频繁创建/销毁数据库连接,减少 CPU 和 IO 负担。
✅ 提高系统性能:数据库连接已经初始化,业务请求可以快速获取连接,减少响应时间。
✅ 统一管理连接:控制最大并发连接数,防止数据库因连接数过多崩溃。
✅ 避免连接泄漏:数据库连接池可以自动回收超时连接,防止资源泄漏。
8.4 常见的数据库连接池
连接池 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
DBCP (Apache) | 速度快,Tomcat 自带 | 存在 Bug,Hibernate3 已不再支持 | 适用于 Tomcat 服务器 |
C3P0 | Hibernate 官方推荐,稳定性好 | 速度比 DBCP 慢 | 适用于 Hibernate 项目 |
Proxool | 支持连接池监控 | 稳定性略低 | 适用于对连接池状态监控要求高的项目 |
BoneCP | 速度快 | 逐渐被 Druid 取代 | 适用于高性能并发应用 |
Druid (阿里巴巴) | 集 DBCP、C3P0、Proxool 优势,支持 SQL 监控 | - | 推荐用于企业级项目 |
👉 推荐使用:Druid
(阿里巴巴)连接池,性能和稳定性最佳。
8.3.1 C3P0数据库连接池
- 获取连接方式一
1 | //使用C3P0数据库连接池的方式,获取数据库的连接:不推荐 |
- 获取连接方式二
1 | //使用C3P0配置文件的方式,获取数据库的连接 |
其中,src下的配置文件为:【c3p0-config.xml】
1 |
|
8.3.2 DBCP数据库连接池
- DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool。如需使用该连接池实现,应在系统中增加如下两个 jar 文件:
- Commons-dbcp.jar:连接池的实现
- Commons-pool.jar:连接池实现的依赖库
- **Tomcat 的连接池正是采用该连接池来实现的。**该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
- 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
- 当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但上面的代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。
- 配置属性说明
属性 | 默认值 | 说明 |
---|---|---|
initialSize | 0 | 连接池启动时创建的初始化连接数量 |
maxActive | 8 | 连接池中可同时连接的最大的连接数 |
maxIdle | 8 | 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制 |
minIdle | 0 | 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接。该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大。 |
maxWait | 无限制 | 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待 |
poolPreparedStatements | false | 开启池的Statement是否prepared |
maxOpenPreparedStatements | 无限制 | 开启池的prepared 后的同时最大连接数 |
minEvictableIdleTimeMillis | 连接池中连接,在时间段内一直空闲, 被逐出连接池的时间 | |
removeAbandonedTimeout | 300 | 超过时间限制,回收没有用(废弃)的连接 |
removeAbandoned | false | 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收 |
- 获取连接方式一:
1 |
|
- 获取连接方式二:
1 | package chapter01; |
其中,src下的配置文件为:【dbcp.properties】
1 | driverClassName=com.mysql.jdbc.Driver |
8.3.3 Druid(德鲁伊)数据库连接池
Druid是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、Proxool等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池,可以说是目前最好的连接池之一。
1 |
|
其中,src下的配置文件为:【druid.properties】
1 | # 数据库连接配置 |
Druid 数据库连接池详细配置参数
参数名称 | 默认值 | 说明 |
---|---|---|
name | - | 连接池名称,多个数据源时用于区分,默认格式:DataSource- + System.identityHashCode(this) |
url | - | 数据库连接 URL,例如: MySQL: jdbc:mysql://localhost:3306/dbname Oracle: jdbc:oracle:thin:@localhost:1521:orcl |
username | - | 数据库用户名 |
password | - | 数据库密码,建议使用 ConfigFilter 进行加密存储,详见 ConfigFilter |
driverClassName | - | JDBC 驱动类名,Druid 会自动识别,但建议手动配置,例如: MySQL: com.mysql.cj.jdbc.Driver Oracle: oracle.jdbc.OracleDriver |
initialSize | 0 | 初始化时创建的物理连接数,第一次 getConnection() 或 init() 触发创建 |
maxActive | 8 | 最大连接数(连接池最大可用连接数量) |
minIdle | - | 最小连接数(空闲时保持的最小连接数量) |
maxWait | - | 获取连接的最大等待时间(毫秒),超时则抛出异常,默认无限等待 |
poolPreparedStatements | false | 是否缓存 PreparedStatement(PSCache),Oracle 建议开启,MySQL 建议关闭 |
maxOpenPreparedStatements | -1 | 最大缓存的 PreparedStatement 数量,大于 0 时,poolPreparedStatements 自动启用,建议 100 |
validationQuery | - | 检测连接是否有效的 SQL 语句,如 SELECT 1 (MySQL)或 SELECT 1 FROM DUAL (Oracle) |
testOnBorrow | true | 获取连接时检查有效性,执行 validationQuery ,影响性能 |
testOnReturn | false | 归还连接时检查有效性,执行 validationQuery ,影响性能 |
testWhileIdle | false | 空闲时检查连接是否有效,timeBetweenEvictionRunsMillis 触发检测,建议设置为 true |
timeBetweenEvictionRunsMillis | - | 检测空闲连接的时间间隔(毫秒),影响 testWhileIdle 逻辑 |
numTestsPerEvictionRun | - | 单次空闲连接回收检测的连接数(Druid 仅支持单个 EvictionRun) |
minEvictableIdleTimeMillis | - | 最小空闲连接存活时间(毫秒),低于该值的连接会被回收 |
connectionInitSqls | - | 物理连接初始化时执行的 SQL 语句 |
exceptionSorter | - | 数据库异常分类处理器,Druid 会自动根据 dbType 选择合适的 ExceptionSorter |
filters | - | 扩展插件配置,可用值:stat (监控统计)log4j (日志)wall (SQL 防御) |
proxyFilters | - | 自定义过滤器,如果 filters 和 proxyFilters 都配置,则 组合 过滤,而非替换 |
推荐配置(示例)
1 | # 数据库连接配置 |