JDBC连接池原理

首先看如下图:

5b06a2a3346e492caa02e78fe70c65a5.png点击并拖拽以移动编辑

图片可能有点丑!!!

(注:上面方块是在连接池里的连接资源,下面火柴人是用户)

1、池子中,我们有4个连接的资源
2、我们有5个用户
3、当我们用户需要的时候呢,就把连接给用户,此时图就成这样了

aea702cf712f4d6cad1f42b2a8e5a343.png点击并拖拽以移动编辑

1、如上图所示,一个用户则用一个连接

2、多出来用户来并没有连接可以用

  • 那么我们有什么好的处理方式呢???

​ (1)、等其他用户用完,我再用

​ (2)、或者重新创建一个连接给连接池,连接池再分配给我们的用户(如图)

7310f2d627fd4d17a0f4cd34d4f89635.png点击并拖拽以移动编辑

#当用户用完之后,会把连接还给连接池,并不关闭

实例 (C3P0连接池)

准备工作 :

​ 1.去谷歌搜索JDBC C3P0,下载C3P0连接池的jar包,解压后,在lib目录下可以找到两个jar包

​ 2.同之前导入mysql的jar包类似,将C3P0的这两个jar包拷贝到IDEA中存放jar包的目录下,右键jar包,选择“**Add as Library…**”将jar加入到项目。 加入成功后可以看到jar包下的子目录

传统方法

C3P0_Demo1类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package connection_pool.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.beans.PropertyVetoException;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
* @author : Cyan_RA9
* @version : 21.0
*/
public class C3P0_Demo1 {
public static void main(String[] args) throws IOException, PropertyVetoException, SQLException {
//创建数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//从properties配置文件中获取相关信息
Properties properties = new Properties();
properties.load(new FileInputStream("src/api/connection/mysql.properties"));
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");

//通过ComboPooledDataSource类的setXxx方法来设置信息
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
//设置连接池初始连接数
comboPooledDataSource.setInitialPoolSize(10);
//设置连接池最大连接数
comboPooledDataSource.setMaxPoolSize(50);
/**
* 初始连接数指连接池被创建后初始化连接的数量;
* 最大连接数指连接池内的连接最多50个;
* 当50个连接全部被使用时,新的连接请求就会进入等待队列。
*/

long start = System.currentTimeMillis();
for (int i = 0; i < 5000; ++i) {
//获取连接
Connection connection = comboPooledDataSource.getConnection();

//释放资源(仅仅是取消了对连接池内连接的引用,连接本身不受影响。
connection.close();
}
long end = System.currentTimeMillis();

System.out.println("使用C3P0连接池后,连接MySQL5000次需要" + (end - start) + "ms");
}
}

点击并拖拽以移动

通过配置文件

c3p0-config.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 数据源名称,代表连接池 -->
<named-config name="Cyan">
<!-- 配置数据库用户名 -->
<property name="user">root</property>
<!-- 配置数据库密码 -->
<property name="password">123456</property>
<!-- 配置数据库URL -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_ex</property>
<!-- 配置数据库驱动 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<!-- 数据库连接池一次性向数据库要多少个连接对象 -->
<property name="acquireIncrement">20</property>
<!-- 初始化连接数 -->
<property name="initialPoolSize">10</property>
<!-- 最小连接数 -->
<property name="minPoolSize">5</property>
<!-- 最大连接数。Default: 15 -->
<property name="maxPoolSize">50</property>
<!-- 可连接的最多命令对象数 -->
<property name="maxStatements">5</property>
<!-- 每个连接对象可连接的最多命令对象数 -->
<property name="maxStatementsPerConnection">2</property>
<!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default:3 -->
<property name="numHelperThreads">3</property>
<!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">3</property>
<!-- 获取连接超时设置 默认是一直等待单位毫秒 -->
<property name="checkoutTimeout">1000</property>
<!--每多少秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">3</property>
<!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">10</property>
<!--配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待它close再断开。配置为0的时候则不会对连接的生存时间进行限制。 -->
<property name="maxIdleTimeExcessConnections">5</property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>
<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。Default: null -->
<property name="automaticTestTable">Test</property>
<!-- 获取connection时测试是否有效 -->
<property name="testConnectionOnCheckin">true</property>
</named-config>
</c3p0-config>

点击并拖拽以移动

C3P0_Demo2类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package connection_pool.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.SQLException;

public class C3P0_Demo2 {
public static void main(String[] args) throws SQLException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("Cyan");

long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
Connection connection = comboPooledDataSource.getConnection();
connection.close();
}
long end = System.currentTimeMillis();
System.out.println("通过配置文件设置参数后,C3P0连接池连接5000次MySQL耗时" + (end - start) + "ms");
}
}

点击并拖拽以移动