一、什么是数据库连接池?
官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。
二、数据库连接池的运行机制
(1) 程序初始化时创建连接池
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池
(4) 程序退出时,断开所有连接,并释放资源
三、数据库连接池的使用
作为开源的数据库连接池,C3P0是一个优秀的连接池,性能也十分可靠。
首先到http://sourceforge.net/projects/c3p0/下载相应的jar包,总共三个,如下图所示。
其次将jar包导入到工程当中,然后就可以使用cp30了。
示例代码如下:
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 }
----------天道酬勤----------------