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

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

官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申

请,使用,释放。

个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们

集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。

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

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

三、数据库连接池的使用

作为开源的数据库连接池,C3P0 是一个优秀的连接池,性能也十分可靠。首先到 http://sourceforge.net/projects/c3p0/ 下载相应的 jar 包,总共三个,

如下图所示。


其次将 jar 包导入到工程当中,然后就可以使用 cp30 了。
示例代码如下:
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
package com.zww.server; 
   
import java.beans.PropertyVetoException; 
import java.sql.Connection; 
import java.sql.SQLException; 
import com.mchange.v2.c3p0.ComboPooledDataSource; 
   
public final class ConnectionManager { 
    //使用单利模式创建数据库连接池 
    private static ConnectionManager instance; 
    private static ComboPooledDataSource dataSource; 
   
    private ConnectionManager() throws SQLException, PropertyVetoException { 
        dataSource = new ComboPooledDataSource(); 
   
        dataSource.setUser("root");     //用户名 
        dataSource.setPassword("123456"); //密码 
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/zww");//数据库地址 
        dataSource.setDriverClass("com.mysql.jdbc.Driver"); 
        dataSource.setInitialPoolSize(5); //初始化连接数 
        dataSource.setMinPoolSize(1);//最小连接数 
        dataSource.setMaxPoolSize(10);//最大连接数 
        dataSource.setMaxStatements(50);//最长等待时间 
        dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒 
    
   
    public static final ConnectionManager getInstance() { 
        if (instance == null) { 
            try
                instance = new ConnectionManager(); 
            } catch (Exception e) { 
                e.printStackTrace(); 
            
        
        return instance; 
    
   
    public synchronized final Connection getConnection() { 
        Connection conn = null
        try
            conn = dataSource.getConnection(); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        
        return conn; 
    
下面是测试代码:
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
package com.zww.server; 
   
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
   
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; 
   
   
public class ConnectionDemo { 
   
    public static void main(String[] args) throws SQLException { 
        System.out.println("使用连接池................................"); 
        for (int i = 0; i < 20; i++) { 
            long beginTime = System.currentTimeMillis(); 
            Connection conn = ConnectionManager.getInstance().getConnection(); 
            try
                PreparedStatement pstmt = conn.prepareStatement("select * from event"); 
                ResultSet rs = pstmt.executeQuery(); 
                while (rs.next()) { 
                     // do nothing... 
                
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } finally
                try
                    conn.close(); 
                } catch (SQLException e) { 
                    e.printStackTrace(); 
                
            
   
            long endTime = System.currentTimeMillis(); 
            System.out.println("第" + (i + 1) + "次执行花费时间为:" + (endTime - beginTime)); 
        
   
        System.out.println("不使用连接池................................"); 
        for (int i = 0; i < 20; i++) { 
            long beginTime = System.currentTimeMillis(); 
            MysqlDataSource mds = new MysqlDataSource(); 
            mds.setURL("jdbc:mysql://localhost:3306/zww"); 
            mds.setUser("root"); 
            mds.setPassword("123456"); 
            Connection conn = mds.getConnection(); 
            try
                PreparedStatement pstmt = conn.prepareStatement("select * from event"); 
                ResultSet rs = pstmt.executeQuery(); 
                while (rs.next()) { 
                                    // do nothing... 
                
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } finally
                try
                    conn.close(); 
                } catch (SQLException e) { 
                    e.printStackTrace(); 
                
            
            long endTime = System.currentTimeMillis(); 
            System.out.println("第" + (i + 1) + "次执行花费时间为:" 
                                + (endTime - beginTime)); 
        
   
    
运行结果如下图所示:

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

转自:http://blog.csdn.net/wenwen091100304/article/details/48035003