C3P0官方文档地址:https://www.mchange.com/projects/c3p0/
一:为什么是C3P0?
- c3p0之前是使用传统的jdbc进行开发,步骤如下:
- 在主程序中建立数据库连接
- 进行sql操作
- 断开数据库连接
- 存在问题
- 普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,在验证用户名和密码(需要耗时0.05~1s左右),需要数据库连接的时候,就向数据库要求一个,执行完成后在断开连接,这样的方式会消耗大量的资源和时间。
- 数据库的连接资源并没有得到很好的重复利用,若同时有几百人甚至几千人在线,频繁的进行数据库连接操作会占用很多系统资源,严重的会造成服务器崩溃。
- 解决方案:数据库连接池,javax.sql.DataSource,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从缓冲池中取出一个,使用完毕后再放回去。
二:C3P0的使用
- 引入jar包或者依赖
- 引入jar包:c3p0 jar下载
- 或者使用maven项目引入依赖
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
- 在项目src目录下创建c3p0-config.xml配置文件,文件名称固定,常用配置内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--testC3p0为配置名称,等会需要引用-->
<named-config name="testC3p0">
<!--配置用户名和密码url等信息-->
<property name="user">chelsea</property>
<property name="password">*********</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement">5</property>
<!--初始缓冲池大小,最小和最大连接数量-->
<property name="initialPoolSize">20</property>
<property name="minPoolSize">2</property>
<property name="maxPoolSize">40</property>
</named-config>
</c3p0-config>
全部配置内容参数可参考官网:官网c3p0配置详解。或者https://blog.csdn.net/liulihui1988/article/details/53405388。个人建议参考官网。
3. 创建工具类读取配置获得链接
- DataSource为类私有变量,且在static代码块中,类初始加载前就引用读取配置,传入的字符串名称为c3p0-config.xml文件中对应的配置名称。
- 外部调用getConnection方法,每次获取一个链接。
- 外部每次调用完成后,调用release方法释放连接
public class JDBCTools {
private static DataSource dataSource;
static{
dataSource = new ComboPooledDataSource("testC3p0");
}
public static Connection getConnection(){
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void release(Connection connection, Statement statement, ResultSet resultSet){
try {
if(connection!=null){
connection.close();
}
if(statement!=null){
statement.close();
}
if(resultSet!=null){
resultSet.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}
}
- 测试,此处和正常使用jdbc相同步骤,获取链接,编写sql,预编译,执行,释放连接。
/**
* 处理图书借阅信息
* @param borrowId
* @param state
* @param adminId
*/
@Override
public void handle(Integer borrowId, Integer state, Integer adminId) {
Connection conn = JDBCTools.getConnection();
PreparedStatement statement = null;
String sql = "update borrow set state = ?,adminid = ? where borrow.id = ?";
try {
statement = conn.prepareStatement(sql);
statement.setInt(1, state);
statement.setInt(2, adminId);
statement.setInt(3,borrowId);
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTools.release(conn,statement,null);
}
}