数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。(用户访问更加高效,消耗资源减少)

数据库连接池的实现

标准接口:DataSource

位于javax.sql包下,通过方法getConnection获取连接

如果Connection对象是从连接池中直接获取的,则调用Connection的close方法不再关闭连接,而是将该连接归还给连接池

数据库连接池一般由数据库厂商直接实现,我们不需要另行实现

  • C3P0:数据库连接池实现技术
  • Druid:数据库连接池实现技术,由阿里巴巴提供

C3P0

使用步骤

  1. 导入jar包:c3p0-0.9.5.5.jar和mchange-commons-java-0.2.19.jar(依赖jar包)另外因为要使用数据库连接对象,所以不要忘记导入mysql-connector-java-8.0.20.jar包
  2. 定义配置文件
    • 名称需为:c3p0.properties或c3p0-config.xml
    • 配置文件路径直接放在src文件夹下即可
  3. 创建核心对象:数据库连接池对象:ComboPooledDataSource
  4. 获取连接:getConnection

C3P0演示类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* C3P0演示类
*/
public class Demo1 {
public static void main(String[] args) throws SQLException {
//创建数据库连接池对象
//在不向ComboPooledDataSource()中传入参数的情况下使用默认配置
//传入指定名称参数,可以使用配置文件中其他的指定配置(使用指定名称的配置)
//这样就只需要一个配置文件即可完成所有数据库连接池的配置
DataSource dataSource=new ComboPooledDataSource();
//获取数据库连接对象
Connection connection=dataSource.getConnection();
//查看获取情况
System.out.println(connection);

}
}

配置文件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
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest</property>
<property name="user">root</property>
<property name="password">rby</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.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest</property>
<property name="user">root</property>
<property name="password">rby</property>

<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>

Druid

使用步骤

  1. 导入jar包:druid-1.1.23.jar和mysql-connector-java-8.0.20.jar
  2. 定义配置文件
    • Druid的配置文件是properties类型的
    • 名称和位置都是任意的
  3. 加载配置文件
  4. 获取数据库连接池对象:通过工厂获取DruidDataSourceFactory
  5. 获取连接:getConnection

Druid演示类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Druid演示
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
//加载配置文件
Properties properties=new Properties();
InputStream is =Demo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//获取连接池对象
DataSource ds= DruidDataSourceFactory.createDataSource(properties);
//获取连接
Connection connection=ds.getConnection();
//打印结果
System.out.println(connection);
}
}

配置文件

1
2
3
4
5
6
7
8
9
10
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest
username=root
password=rby
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 最大等待数
maxWait=3000

利用Druid实现工具类

Druid工具类

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Druid工具类
*/

public class DruidUtils {

//定义成员变量
private static DataSource dataSource;

/*
* 在静态代码块中加载配置文件,并且获取连接池对象,这些都是只需要进行一次的操作
*/
static {
try {
//加载配置文件
Properties properties = new Properties();
InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//获取连接池对象
dataSource=DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 获取连接池对象
* @return 连接池对象
* @throws Exception
*/
public static DataSource getDataSource() throws Exception {
return dataSource;
}

/**
* 获取数据库连接对象
* @return 数据库连接对象
* @throws Exception
*/
public static Connection getConnection() throws Exception {
return dataSource.getConnection();
}

/**
* 释放数据库连接资源
* @param rs 数据库结果集
* @param connection 数据库连接对象
* @param statement sql语句执行对象
*/
public static void close(ResultSet rs, Connection connection, Statement statement){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}

if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}

if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}

}
/**
* 释放数据库连接资源
* @param connection 数据库连接对象
* @param statement sql语句执行对象
*/
public static void close(Connection connection, Statement statement){

if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}

if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}

}
}

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Demo2 {
public static void main(String[] args) {
Connection connection=null;
PreparedStatement statement = null;
ResultSet rs=null;
try {
//利用工具来获取连接对象
connection = DruidUtils.getConnection();
String sql="select * from loginMess;";
statement=connection.prepareStatement(sql);
rs=statement.executeQuery();
while (rs.next()){
String user=rs.getString(2);
String pass=rs.getString(3);
System.out.println(user+" : "+pass);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DruidUtils.close(rs,connection,statement);
}

}
}