博学谷IT提供技术支持
一、概述
数据库连接池是一种众所周知的数据访问模式。其主要目的是减少执行数据库连接和读/写数据库操作所涉及的开销。
在最根本的层面上, 连接池是一种数据库连接缓存实现 ,可以根据特定需求进行配置。
在这里,我们将讨论一些流行的连接池框架。然后我们将学习如何从头开始实现我们自己的连接池。
2. 为什么要有连接池
如果我们分析数据库连接所涉及的生命周期,我们就会明白为什么:
- 使用数据库驱动程序打开到数据库的连接
- 打开TCP 通道以读取/写入数据
- 关闭TCP 通道
- 关闭数据库的连接
很明显,数据库连接是相当耗费资源的操作,因此在每个可能的用例中都应该减少到最低限度
这就是连接池发挥作用的地方。
通过简单地实现一个数据库连接容器,它允许我们重用许多现有的连接,我们可以有效地节省执行大量数据库连接的成本。这提高了我们的应用程序的整体性能。
3. JDBC 连接池框架
从实用的角度来看,考虑到已开源的连接池框架的数量,从头开始实现连接池是没有意义的。
3.1 Apache Commons DBCP
让我们从Apache Commons DBCP Component开始,这是一个功能齐全的连接池 JDBC 框架:
public class DBCPDataSource {
private static BasicDataSource ds = new BasicDataSource();
static {
ds.setUrl("jdbc:h2:mem:test");
ds.setUsername("user");
ds.setPassword("password");
ds.setMinIdle(5);
ds.setMaxIdle(10);
ds.setMaxOpenPreparedStatements(100);
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
private DBCPDataSource(){ }
}
在这种情况下,我们使用静态代码块来轻松配置 DBCP 的属性。
以下是如何获得与DBCPDataSource类的连接:
Connection con = DBCPDataSource.getConnection();
3.2 HikariCP
现在让我们看看HikariCP ,这是一个由Brett Wooldridge创建的闪电般的 JDBC 连接池框架
public class HikariCPDataSource {
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;
static {
config.setJdbcUrl("jdbc:h2:mem:test");
config.setUsername("user");
config.setPassword("password");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
ds = new HikariDataSource(config);
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
private HikariCPDataSource(){}
}
同样,这里是如何获得与HikariCPDataSource类的池连接
Connection con = HikariCPDataSource.getConnection();
3.3 C3P0
public class C3p0DataSource {
private static ComboPooledDataSource cpds = new ComboPooledDataSource();
static {
try {
cpds.setDriverClass("org.h2.Driver");
cpds.setJdbcUrl("jdbc:h2:mem:test");
cpds.setUser("user");
cpds.setPassword("password");
} catch (PropertyVetoException e) {
// handle the exception
}
}
public static Connection getConnection() throws SQLException {
return cpds.getConnection();
}
private C3p0DataSource(){}
}
使用C3p0DataSource类获取池连接类似于前面的示例:
Connection con = C3p0DataSource.getConnection();