版权声明:转载请注明原始链接 https://blog.csdn.net/sswqzx/article/details/82731870
学习目标
C3p0数据库连接池
一、c3p0数据库连接池
1、概述:
c3p0是一个开源的JDBC连接池、它实现了数据源和JNDI(Java Naming and Directory Interface,Java命名和目录接口)绑定、支持jdbc3和jdbc2的标准拓展、目前使用它的开源项目有Hibernate,Spring等c3p0 开发包下载: http://sourceforge.net
对比图说明c3p0优点:
总结::节省创建连接与释放连接的性能消耗 ---- 连接池中连接起到复用的作用,提高程序性能. 降低了数据库的压力.
2、配置c3p0
手动
// 核心连接池类
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
// 设置四个JDBC基本连接属性
comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql:///day04");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("123");
特别注意 : MySQL 驱动 8 版本之后关于 driverClass 与 url 参数的书写变化 :
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false
3、硬编码、手动书写配置参数
// 硬编码 :
@Test
public void test1() throws PropertyVetoException {
// 1. 创建了一个核心类对象 :
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// DataSource dataSource = new ComboPooledDataSource();
// 2. 设置了四个核心参数
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false");
dataSource.setUser("root");
dataSource.setPassword("123456");
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 0; i < 10; i++) {
try {
// 3. 获取连接 (不要新建, 应该从连接池中直接获取)
conn = dataSource.getConnection();
// 4. 操作数据
String sql = "select * from user;";
// 预编译
stmt = conn.prepareStatement(sql);
// 直接执行
rs = stmt.executeQuery();
// 遍历结果集
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
// System.out.println(id + " : " + username + " : " + password + " : " + email);
}
System.out.println(i + " conn = " + conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 5. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}
}
4、软编码:配置文件写在xml中
在src下新建c3p0-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false </property>
<property name="user">root</property>
<property name="password">ssw</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="baidu">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false</property>
<property name="user">root</property>
<property name="password">ssw</property>
</named-config>
</c3p0-config>
常用基本连接池属性
acquireIncrement 如果连接池中连接都被使用了,一次性增长3个新的连接
initialPoolSize 连接池中初始化连接数量 默认:3
maxPoolSize 最大连接池中连接数量 默认:15连接
maxIdleTime 如果连接长时间没有使用,将被回收 默认:0 连接永不过期
minPoolSize 连接池中最小连接数量 默认:3
代码实现:
// 软编码 : 配置文件
@Test
public void test2() throws PropertyVetoException {
// 1. 创建了一个核心类对象 :
// new ComboPooledDataSource(); 自动寻找一个文件. 在 src 目录下寻找 c3p0-config.xml 文件.
// 如果有, 自动加载该 xml 文件中的数据, 如果没有, 报错.
// DataSource dataSource = new ComboPooledDataSource("baidu"); // 名称配置
DataSource dataSource = new ComboPooledDataSource(); // 默认配置
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 0; i < 10; i++) {
try {
// 3. 获取连接 (不要新建, 应该从连接池中直接获取)
conn = dataSource.getConnection();
// 4. 操作数据
String sql = "select * from user;";
// 预编译
stmt = conn.prepareStatement(sql);
// 直接执行
rs = stmt.executeQuery();
// 遍历结果集
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
// System.out.println(id + " : " + username + " : " + password + " : " + email);
}
System.out.println(i + " conn = " + conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 5. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}
}
5、最终版、将JDBCUtils工具类实现c3p0封装(重点)
A、配置文件:c3p0-config.xml 数据库连接池配置文件 : 需要创建在 src 目录下.
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<!-- 默认配置,c3p0框架默认加载这段默认配置 -->
<default-config>
<!-- 配置JDBC 四个基本属性 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false </property>
<property name="user">root</property>
<property name="password">ssw</property>
</default-config>
<!-- 可以自定义配置,为这段配置起一个名字,c3p0指定名称加载配置 -->
<named-config name="baidu">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false</property>
<property name="user">root</property>
<property name="password">ssw</property>
</named-config>
</c3p0-config>
B、c3p0工具类:
public class JDBCUtils {
// 属性 (数据)
// 默认加载 位置: src 名称: c3p0-config.xml 文件.
private static final DataSource dataSource = new ComboPooledDataSource();
// 提供 : 给 dataSource 提供一个 getter 方法
public static DataSource getDataSource() {
return dataSource;
}
// 2. 获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
// 3. 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
release(conn, stmt);
}
public static void release(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close(); // Spring AOP
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
C、测试类代码:
// JDBC 连接操作的代码
@Test
public void test3() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
for (int i = 0; i < 10; i++) {
try {
// 1. 获取连接 (不要新建, 应该从连接池中直接获取)
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "select * from user;";
// 预编译
stmt = conn.prepareStatement(sql);
// 直接执行
rs = stmt.executeQuery();
// 遍历结果集
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
// System.out.println(id + " : " + username + " : " + password + " : " + email);
}
System.out.println(i + " conn = " + conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}
}
总结:上图可以看到一个@5c7bfdc1 连接对象被使用多次。最终版是我们要记住的。其他只是个过程。