数据库连接池
1.JDBC流程
- 加载驱动(加载到内存一次)
- 建立数据库连接(Connection)
- 执行SQL语句(Statement、PreparedStatement)
- ResultSet 接收结果(查找时才用到)
- 断开连接,释放资源(close)
数据库连接池是针对JDBC开发过程建立数据库连接实现的一个优化。
数据库连接对象是通过DriverManager来获取对象的,每次获取都需要向数据库申请连接,验证用户名和密码。连接成功后,执行SQL语句后释放资源(舍弃掉),这会造成资源的浪费。
基本思想:
给数据库建立一个缓冲池,预先给连接池放入一定数量的连接对象,需要获取连接对象的时候,直接从连接池中获取,用完之后放回到缓冲池中,做到资源重复利用。
当数据库缓冲池中没有空间的连接对象时,则其他连接请求会进入等待队列,等待空闲连接的出现,从而使用。
传统连接:
连接池连接:
2.数据库连接池实现
JDBC的数据库连接池使用javax.sql.DataSource接口完成。DataSource是JDK官方提供的一个借口,使用时开发者不需要自己去实现接口,可以通过第三方工具去实现,C3P0是一个常用的第三方实现,可以实现连接。
2.1导入jar包
需要引入两个jar包:
2.2代码实现:
package com.myl;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @ClassName: C3P0
* @Description: TODO
* @author: meyolo
* @date: 2020/10/4 18:24
*/
public class C3P0 {
public static void main(String[] args) {
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection =dataSource.getConnection();
System.out.println(connection);
connection.close();
} catch (PropertyVetoException e) {
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
}
}
2.3实际使用:
1.通过调用datasource中的各种方法实现功能。
2.通过加载xml文件实现功能(效率快)。
-
配置文件的名字必须是c3p0-config.xml
-
ComboPooledDataSource构造参数传递的是xml文件中name属性值。
package com.myl;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @ClassName: C3P0
* @Description: TODO
* @author: meyolo
* @date: 2020/10/4 18:24
*/
public class C3P0 {
public static void main(String[] args) {
try {
//这里有无参构造和有参构造,无参构造通过调用datasoure方法实现配置,有参通过加载xml文件实现(参数为xml文件里配置的name值)
ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0");
// dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
// dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");
// dataSource.setUser("root");
// dataSource.setPassword("root");
Connection connection =dataSource.getConnection();
//设置初始化连接个数
// dataSource.setInitialPoolSize(10);
//设置最大连接数
// dataSource.setMaxPoolSize(20);
//设置最小连接数(当连接池对象不够用时的判断条件(剩余2个时,认为用完))
// dataSource.setMinPoolSize(2);
//连接对象不够用时,再次申请的个数
// dataSource.setAcquireIncrement(5);
System.out.println(connection);
//还回到数据库连接池中,此处调用close()方法,与传统close()不一样,这是放回到连接池中,传统则是舍弃。
connection.close();
} catch (SQLException e){
e.printStackTrace();
}
}
}
c3p0-config.xml文件:
<?xml version="1.0" encoding="utf-8" ?>
<c3p0-config>
<named-config name="testc3p0">
<!-- 连接数据源的基本属性-->
<property name="user">root</property>
<property name="password">root</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC</property>
<!-- 连接对象不够用时,再次申请的个数-->
<property name="acquireIncrement">5</property>
<!-- 设置初始化连接个数-->
<property name="initialPoolSize">20</property>
<!-- 设置最小连接数(当连接池对象不够用时的判断条件(剩余2个时,认为用完))-->
<property name="minPoolSize">2</property>
<!-- 设置最大连接数-->
<property name="maxPoolSize">30</property>
</named-config>
</c3p0-config>
roperty name=“minPoolSize”>2
<property name="maxPoolSize">30</property>
</named-config>
```