本文目录导读:

- Maven依赖配置
- C3P0配置文件(c3p0-config.xml)
- JDBC工具类(JDBCUtils.java)
- 数据访问测试类(UserDao.java)
- 测试主类(Main.java)
- properties配置方式(可选)
- 注意事项
我来为您提供一个完整的C3P0连接池使用案例,包括配置文件和Java代码示例。
Maven依赖配置
<dependencies>
<!-- C3P0连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 或使用MSSQL -->
<!--
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.1.jre8</version>
</dependency>
-->
</dependencies>
C3P0配置文件(c3p0-config.xml)
在项目的src/main/resources目录下创建c3p0-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置 -->
<default-config>
<!-- 数据库连接基础信息 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">5</property>
<!-- 最大连接数 -->
<property name="maxPoolSize">20</property>
<!-- 最小连接数 -->
<property name="minPoolSize">5</property>
<!-- 获取连接失败时,从数据库获取新连接的次数 -->
<property name="acquireRetryAttempts">30</property>
<!-- 两次连接中间隔时间,单位毫秒 -->
<property name="acquireRetryDelay">1000</property>
<!-- 连接测试间隔时间,单位秒 -->
<property name="testConnectionOnCheckout">true</property>
<!-- 连接空闲时间,单位秒,超过时间则被回收 -->
<property name="maxIdleTime">60</property>
<!-- 连接最大空闲时间 -->
<property name="maxIdleTimeExcessConnections">30</property>
<!-- 定期清理连接的间隔时间 -->
<property name="idleConnectionTestPeriod">30</property>
<!-- 每次获取连接时测试是否有效 -->
<property name="preferredTestQuery">SELECT 1</property>
<!-- 连接耗尽时的增长数 -->
<property name="acquireIncrement">5</property>
<!-- 每个连接的最大缓存Statement数量 -->
<property name="maxStatements">50</property>
<!-- 每个连接中缓存Statement的最大数量 -->
<property name="maxStatementsPerConnection">10</property>
<!-- 连接池中不重要的连接数 -->
<property name="unreturnedConnectionTimeout">300</property>
<!-- 调试模式 -->
<property name="debugUnreturnedConnectionStackTraces">false</property>
</default-config>
<!-- 命名配置 -->
<named-config name="mysql-config">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mysql_db?useSSL=false&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">3</property>
<property name="minPoolSize">3</property>
<property name="maxPoolSize">15</property>
<property name="acquireIncrement">5</property>
<property name="maxStatements">50</property>
<property name="testConnectionOnCheckout">true</property>
<property name="preferredTestQuery">SELECT 1</property>
</named-config>
</c3p0-config>
JDBC工具类(JDBCUtils.java)
package com.example.util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCUtils {
private static DataSource dataSource = null;
// 静态代码块初始化数据源
static {
try {
// 使用默认配置
dataSource = new ComboPooledDataSource();
// 或者使用命名配置
// dataSource = new ComboPooledDataSource("mysql-config");
} catch (Exception e) {
e.printStackTrace();
throw new ExceptionInInitializerError("C3P0连接池初始化失败");
}
}
/**
* 获取数据库连接
*/
public static Connection getConnection() throws SQLException {
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 释放资源
*/
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 通用增删改方法
*/
public static int update(String sql, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
// 设置参数
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
return -1;
} finally {
close(conn, pstmt, null);
}
}
/**
* 获取数据源
*/
public static DataSource getDataSource() {
return dataSource;
}
}
数据访问测试类(UserDao.java)
package com.example.dao;
import com.example.util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
// 创建用户表
public static void createUserTable() {
String sql = "CREATE TABLE IF NOT EXISTS user (" +
"id INT PRIMARY KEY AUTO_INCREMENT," +
"username VARCHAR(50) NOT NULL," +
"password VARCHAR(50) NOT NULL," +
"age INT," +
"email VARCHAR(100)," +
"created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
")";
int result = JDBCUtils.update(sql);
System.out.println("创建表结果: " + (result == -1 ? "失败" : "成功"));
}
// 插入用户
public static int insertUser(String username, String password, Integer age, String email) {
String sql = "INSERT INTO user (username, password, age, email) VALUES (?, ?, ?, ?)";
return JDBCUtils.update(sql, username, password, age, email);
}
// 查询所有用户
public static List<String> selectAllUsers() {
List<String> userList = new ArrayList<>();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "SELECT * FROM user";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
int age = rs.getInt("age");
String email = rs.getString("email");
userList.add(String.format("ID: %d, 用户名: %s, 密码: %s, 年龄: %d, 邮箱: %s",
id, username, password, age, email));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(conn, pstmt, rs);
}
return userList;
}
// 根据用户名查询用户
public static void selectUserByUsername(String username) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "SELECT * FROM user WHERE username = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println("找到用户: " +
"ID=" + rs.getInt("id") +
", 用户名=" + rs.getString("username") +
", 年龄=" + rs.getInt("age") +
", 邮箱=" + rs.getString("email"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(conn, pstmt, rs);
}
}
// 更新用户信息
public static int updateUser(int id, String username, Integer age) {
String sql = "UPDATE user SET username = ?, age = ? WHERE id = ?";
return JDBCUtils.update(sql, username, age, id);
}
// 删除用户
public static int deleteUser(int id) {
String sql = "DELETE FROM user WHERE id = ?";
return JDBCUtils.update(sql, id);
}
}
测试主类(Main.java)
package com.example;
import com.example.dao.UserDao;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 1. 创建用户表
UserDao.createUserTable();
// 2. 插入多个用户
int result1 = UserDao.insertUser("张三", "123456", 25, "zhangsan@example.com");
int result2 = UserDao.insertUser("李四", "abcdef", 30, "lisi@example.com");
int result3 = UserDao.insertUser("王五", "654321", 28, "wangwu@example.com");
System.out.println("插入结果: 张三=" + result1 + ", 李四=" + result2 + ", 王五=" + result3);
// 3. 查询所有用户
System.out.println("\n=== 查询所有用户 ===");
List<String> users = UserDao.selectAllUsers();
for (String user : users) {
System.out.println(user);
}
// 4. 根据用户名查询
System.out.println("\n=== 查询用户名包含'张'的用户 ===");
UserDao.selectUserByUsername("张");
// 5. 更新用户信息
System.out.println("\n=== 更新用户ID=1的信息 ===");
int updateResult = UserDao.updateUser(1, "张三丰", 35);
System.out.println("更新结果: " + (updateResult > 0 ? "成功" : "失败"));
// 6. 删除用户
System.out.println("\n=== 删除用户ID=2 ===");
int deleteResult = UserDao.deleteUser(2);
System.out.println("删除结果: " + (deleteResult > 0 ? "成功" : "失败"));
// 7. 最终查询验证
System.out.println("\n=== 最终用户列表 ===");
users = UserDao.selectAllUsers();
for (String user : users) {
System.out.println(user);
}
}
}
properties配置方式(可选)
除了XML配置,也可以使用properties文件配置(c3p0.properties):
# c3p0.properties c3p0.driverClass=com.mysql.cj.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC c3p0.user=root c3p0.password=123456 # 连接池配置 c3p0.initialPoolSize=5 c3p0.minPoolSize=5 c3p0.maxPoolSize=20 c3p0.acquireIncrement=5 c3p0.maxStatements=50 c3p0.maxStatementsPerConnection=10 c3p0.testConnectionOnCheckout=true c3p0.preferredTestQuery=SELECT 1 c3p0.maxIdleTime=60 c3p0.idleConnectionTestPeriod=30
注意事项
-
配置文件路径:c3p0-config.xml必须放在classpath下(
src/main/resources)。 -
数据库驱动:根据你使用的数据库选择合适的驱动类。
- MySQL 8.x:
com.mysql.cj.jdbc.Driver - MySQL 5.x:
com.mysql.jdbc.Driver - PostgreSQL:
org.postgresql.Driver
- MySQL 8.x:
-
连接测试:
testConnectionOnCheckout=true表示每次获取连接时都测试,这会影响性能,在生产环境建议设置为false。 -
资源关闭:使用完毕后一定要关闭连接,释放回连接池。
-
连接池监控:可以通过C3P0提供的API查看连接池状态。
// 查看连接池状态
ComboPooledDataSource cpds = (ComboPooledDataSource) JDBCUtils.getDataSource();
System.out.println("活动连接数: " + cpds.getNumBusyConnections());
System.out.println("空闲连接数: " + cpds.getNumIdleConnections());
System.out.println("总连接数: " + cpds.getNumConnections());
这个案例展示了C3P0连接池的基本使用,包括配置、工具类封装和实际业务操作,您可以根据实际需求修改数据库连接信息和连接池参数。