用我自己的话理解,相当于在一个池子里获取到一些数据库连接对象,
随拿随用,用完不是丢掉,而是放回池子,实现了数据库操作对象的复用。
以前都是获取完一个数据库操作对象,用完就调用 .close()方法释放了资源,
下次用的时候,必须重新请求获取,频繁的请求和丢弃,造成程序运行效率低下。
c3p0数据库连接池技术:
1.导入两个 jar 包 c3p0-0.9.5.2.jar 和 mchange-comments-java-0.2.12.jar
1.1 不要忘记导入数据库的驱动 jar 包 mysql-connector.jar
1.2 下载地址:c3p0下载:https://www.mchange.com/projects/c3p0
2.定义配置文件:
2.1 名称:c3p0.properties 或者 c3p0-config.xml(推荐)
2.2 路径:直接放在 src 目录下即可
3.创建核心对象 ==> 数据库连接池对象 ComboPooledDataSource
4.获取连接 getConnection
- 配置文件代码模板:
- 提示: 超时时间单位是毫秒 ms , 我们设置为 3000ms,即 3 秒。
- 配置了2 个,一个是默认的,另一个是 otherc3p0, 结构是一样的。
<!-- c3p0-config.xml -->
<c3p0-config>
<!-- 使用默认的配置读取连接池对象-->
<default-config>
<!-- 连接参数-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/school</property>
<property name="user">root</property>
<property name="password">root</property>
<!--连接池参数-->
<!-- 初始化申请的连接数量 -->
<property name="initialPoolSize">5</property>
<!-- 申请的最大连接数量 -->
<property name="maxPoolSize">10</property>
<!-- 超时时间 -->
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/school</property>
<property name="user">root</property>
<property name="password">root</property>
<!--连接池参数-->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
-
- 创建一个此时类,在 main 方法里进行以下三步操作
-
- 创建数据库连接池对象
-
- 获取连接对象
-
- 打印连接对象
public class C3p0Demo1 {
public static void main(String[] args) throws SQLException {
// 1. 创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
// 2. 获取连接对象
Connection conn = ds.getConnection();
// 3. 打印conn
System.out.println(conn);
}
}
输出结果:
红色的不是错误信息,而是打印出的日志,
绿框中打印出了数据库连接池操作对象!
情况 2:假设我们想打印出这 10 个连接对象,使用 for 循环。
public class C3p0Demo2 {
public static void main(String[] args) throws SQLException {
// 1. 获取 DataSource 对象
DataSource ds = new ComboPooledDataSource();
// 2. 获取连接
for (int i = 1;i<=10;i++) {
Connection conn = ds.getConnection();
System.out.println(i + ":" + conn);
}
}
}
输出结果:顺利打印出了 10 个连接对象
如果我们想打印 11 个连接对象,后会出现什么情况?因为连接池最大连接对象设置的是 10 个, 所以会有错误。
public class C3p0Demo2 {
public static void main(String[] args) throws SQLException {
// 1. 获取 DataSource 对象
DataSource ds = new ComboPooledDataSource();
// 2. 获取连接(只改变循环条件)
for (int i = 1;i<=11;i++) {
Connection conn = ds.getConnection();
System.out.println(i + ":" + conn);
}
}
}
输出结果:同时请求 11 个连接,前 10 个连接对象顺利打印出来,第十一个等待了 3s 才打印出来。
情况 3:如果我们确实想获得 11 个连接对象,但是池子里只有 10 个怎么办?答案是: 请求过程中,释放掉其中一个连接,第 11 个就能顺利获取到了。
public class C3p0Demo2 {
public static void main(String[] args) throws SQLException {
// 1. 获取 DataSource 对象
DataSource ds = new ComboPooledDataSource();
// 2. 获取连接
for (int i = 1;i<=11;i++) {
Connection conn = ds.getConnection();
System.out.println(i + ":" + conn);
if (i == 5){
conn.close();//获取到第 5 个连接后,再把资源归还
}
}
}
}
输出结果:顺利的获取到了 11个对象,因为第 5 个用完后,归还了连接。
至此,我们已经完成了 c3p0 的入门操作,后续会进一步深入 数据库 Pool(池)技术。