数据库连接池是什么?
数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
在对数据库进行操作之前都要先获取数据库连接,然后才能向后进行操作,增删改查,获取结果集,浪费时间的地方就是在获取数据库连接上,以往每次操作的时候,先获取连接,操作完之后关掉连接,这么一次一次,时间都浪费在获取连接上了,我们需要的就是一个数据库连接池,先创建好一定数量的连接放在池子里,当我们要用的时候,去池子中去找可用的连接,当用完之后,再把连接放回池子中,这样我们用的连接都是池子负责管理的,每次用完之后只要放回去,这样相比于之前的获取到连接,用完关闭速度很快,只是把连接拿来不用每次都创建,关闭,可以省很多的时间。
使用c3p0可以很轻松地构建数据库连接池,是一个开源的项目,https://sourceforge.net/projects/c3p0/files/?source=navbar下载网址,一个压缩包中包含jar包和例子,说明
需要的jar包,导入我们的项目中就能使用了
使用单例模式(饿汉式)构建数据库连接池,
private static ComboPooledDataSource dataSource;
private static ConnectionManager connectionManager = new ConnectionManager();
private ConnectionManager(){
try {
//ComboPooledDataSource cpds = new ComboPooledDataSource();
// cpds.setDriverClass(“org.postgresql.Driver”);
// 加载jdbc驱动程序cpds.setJdbcUrl(“jdbc:postgresql:localhost / testdb”);
// cpds.setUser( “swaldman”);
// cpds.setPassword( “测试密码”);
// 下面的设置是可选的 - c3p0可以使用默认值
// cpds.setMinPoolSize(5);
// cpds.setAcquireIncrement(5);
// cpds.setMaxPoolSize(20); // DataSource cpds现在是一个完全配置和可用的汇集数据源...
dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mail");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setInitialPoolSize(5); //初始化连接数
dataSource.setMinPoolSize(1);//最小连接数
dataSource.setMaxPoolSize(20);//最大连接数
dataSource.setMaxStatements(50);//最长等待时间
dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
public static ConnectionManager getInstance(){
return connectionManager;
}
public synchronized Connection getConnection() {
Connection conn = null;
try {
conn=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
在下载的说明文档中也介绍了使用方法
在main方法中测试,输出两种方法所用的时间
public static void main(String[] args) throws SQLException {
for(int i=0;i<50;i++) {
long begin = System.currentTimeMillis();
Connection conn = ConnectionManager.getInstance().getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT * FROM USER WHERE id=2");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
}
conn.close();
ps.close();
rs.close();
long end = System.currentTimeMillis();
System.out.print(end-begin+" ");
}
System.out.println("-------------");
for(int i=0;i<50;i++) {
long begin = System.currentTimeMillis();
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mail";
String username = "root";
String password = "root";
conn = DriverManager.getConnection(url, username, password);
PreparedStatement ps = conn.prepareStatement("SELECT * FROM USER WHERE id=2");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
}
conn.close();
ps.close();
rs.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.print(end - begin+" ");
}
}
输出:
利用数据库连接池第一次使用耗时时间长,以后平均用时均为1ms,不使用连接池的代码平均都在15ms左右