博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据库连接池的理解和使用

Posted on 2017-08-04 11:22  激流勇进、  阅读(343)  评论(1编辑  收藏  举报

一、什么是数据库连接池?

官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。

二、数据库连接池的运行机制

(1)  程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源

三、数据库连接池的使用

作为开源的数据库连接池,C3P0是一个优秀的连接池,性能也十分可靠。



首先到http://sourceforge.net/projects/c3p0/下载相应的jar包,总共三个,如下图所示。
 
其次将jar包导入到工程当中,然后就可以使用cp30了。
示例代码如下:
 1 package com.zww.server;  
 2   
 3 import java.beans.PropertyVetoException;  
 4 import java.sql.Connection;  
 5 import java.sql.SQLException;  
 6 import com.mchange.v2.c3p0.ComboPooledDataSource;  
 7   
 8 public final class ConnectionManager {  
 9     //使用单利模式创建数据库连接池  
10     private static ConnectionManager instance;  
11     private static ComboPooledDataSource dataSource;  
12   
13     private ConnectionManager() throws SQLException, PropertyVetoException {  
14         dataSource = new ComboPooledDataSource();  
15   
16         dataSource.setUser("root");     //用户名  
17         dataSource.setPassword("123456"); //密码  
18         dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/zww");//数据库地址  
19         dataSource.setDriverClass("com.mysql.jdbc.Driver");  
20         dataSource.setInitialPoolSize(5); //初始化连接数  
21         dataSource.setMinPoolSize(1);//最小连接数  
22         dataSource.setMaxPoolSize(10);//最大连接数  
23         dataSource.setMaxStatements(50);//最长等待时间  
24         dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒  
25     }  
26   
27     public static final ConnectionManager getInstance() {  
28         if (instance == null) {  
29             try {  
30                 instance = new ConnectionManager();  
31             } catch (Exception e) {  
32                 e.printStackTrace();  
33             }  
34         }  
35         return instance;  
36     }  
37   
38     public synchronized final Connection getConnection() {  
39         Connection conn = null;  
40         try {  
41             conn = dataSource.getConnection();  
42         } catch (SQLException e) {  
43             e.printStackTrace();  
44         }  
45         return conn;  
46     }  
47 }  

 

 
下面是测试代码:
 1 package com.zww.server;  
 2   
 3 import java.sql.Connection;  
 4 import java.sql.PreparedStatement;  
 5 import java.sql.ResultSet;  
 6 import java.sql.SQLException;  
 7   
 8 import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;  
 9   
10   
11 public class ConnectionDemo {  
12   
13     public static void main(String[] args) throws SQLException {  
14         System.out.println("使用连接池................................");  
15         for (int i = 0; i < 20; i++) {  
16             long beginTime = System.currentTimeMillis();  
17             Connection conn = ConnectionManager.getInstance().getConnection();  
18             try {  
19                 PreparedStatement pstmt = conn.prepareStatement("select * from event");  
20                 ResultSet rs = pstmt.executeQuery();  
21                 while (rs.next()) {  
22                      // do nothing...  
23                 }  
24             } catch (SQLException e) {  
25                 e.printStackTrace();  
26             } finally {  
27                 try {  
28                     conn.close();  
29                 } catch (SQLException e) {  
30                     e.printStackTrace();  
31                 }  
32             }  
33   
34             long endTime = System.currentTimeMillis();  
35             System.out.println("第" + (i + 1) + "次执行花费时间为:" + (endTime - beginTime));  
36         }  
37   
38         System.out.println("不使用连接池................................");  
39         for (int i = 0; i < 20; i++) {  
40             long beginTime = System.currentTimeMillis();  
41             MysqlDataSource mds = new MysqlDataSource();  
42             mds.setURL("jdbc:mysql://localhost:3306/zww");  
43             mds.setUser("root");  
44             mds.setPassword("123456");  
45             Connection conn = mds.getConnection();  
46             try {  
47                 PreparedStatement pstmt = conn.prepareStatement("select * from event");  
48                 ResultSet rs = pstmt.executeQuery();  
49                 while (rs.next()) {  
50                                     // do nothing...  
51                 }  
52             } catch (SQLException e) {  
53                 e.printStackTrace();  
54             } finally {  
55                 try {  
56                     conn.close();  
57                 } catch (SQLException e) {  
58                     e.printStackTrace();  
59                 }  
60             }  
61             long endTime = System.currentTimeMillis();  
62             System.out.println("第" + (i + 1) + "次执行花费时间为:"  
63                                 + (endTime - beginTime));  
64         }  
65   
66     }  

 


 运行结果如下图所示:

测试结果表明,在使用连接池时,只在第一次初始化时,比较耗时,完成初始化之后,使用连接池进行数据库操作明显比不使用连接池花费的时间少。

 1  1 package com.zww.server;  
 2  2   
 3  3 import java.beans.PropertyVetoException;  
 4  4 import java.sql.Connection;  
 5  5 import java.sql.SQLException;  
 6  6 import com.mchange.v2.c3p0.ComboPooledDataSource;  
 7  7   
 8  8 public final class ConnectionManager {  
 9  9     //使用单利模式创建数据库连接池  
10 10     private static ConnectionManager instance;  
11 11     private static ComboPooledDataSource dataSource;  
12 12   
13 13     private ConnectionManager() throws SQLException, PropertyVetoException {  
14 14         dataSource = new ComboPooledDataSource();  
15 15   
16 16         dataSource.setUser("root");     //用户名  
17 17         dataSource.setPassword("123456"); //密码  
18 18         dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/zww");//数据库地址  
19 19         dataSource.setDriverClass("com.mysql.jdbc.Driver");  
20 20         dataSource.setInitialPoolSize(5); //初始化连接数  
21 21         dataSource.setMinPoolSize(1);//最小连接数  
22 22         dataSource.setMaxPoolSize(10);//最大连接数  
23 23         dataSource.setMaxStatements(50);//最长等待时间  
24 24         dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒  
25 25     }  
26 26   
27 27     public static final ConnectionManager getInstance() {  
28 28         if (instance == null) {  
29 29             try {  
30 30                 instance = new ConnectionManager();  
31 31             } catch (Exception e) {  
32 32                 e.printStackTrace();  
33 33             }  
34 34         }  
35 35         return instance;  
36 36     }  
37 37   
38 38     public synchronized final Connection getConnection() {  
39 39         Connection conn = null;  
40 40         try {  
41 41             conn = dataSource.getConnection();  
42 42         } catch (SQLException e) {  
43 43             e.printStackTrace();  
44 44         }  
45 45         return conn;  
46 46     }  
47 47 }