为什么需要连接池?
在应用程序中,每次与数据库的交互都需要建立新连接,这不仅增加了延迟,还会消耗大量资源。使用连接池,可以避免重复创建和销毁连接的开销,从而提高性能。连接池会维护一定数量的数据库连接,可以重复使用,可以提高应用的响应效率和便于维护。
常用的连接池都有哪些
HikariCP(HikariCP 是用于创建和管理连接,利用“池”的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制、连接可靠性测试、连接泄露控制、缓存语句等功能,另外,和 druid 一样,HikariCP 也支持监控功能。HikariCP 是目前最快的连接池,就连风靡一时的BoneCP 也停止维护,主动让位给它,SpringBoot 也把它设置为默认连接池)
Apache DBCP(Apache DBCP数据源是Apache软件基金会下的一个开源数据库连接池实现,主要用于管理数据库连接,提高数据库访问性能和效率。DBCP(DataBase Connection Pool)依赖于Commons-pool库,主要用于Apache Tomcat的连接池实现)
C3P0 (C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。使用它的开源项目有Hibernate、Spring等)
c3p0与dbcp区别:dbcp没有自动回收空闲连接的功能,c3p0有自动回收空闲连接功能
这里我用HikariCP+clickhouse数据库来使用数据源举例,C3P0用于mySql较多,等等。 项目中,maven导入依赖:
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.3.2-patch7</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
DataSourcePool:
public class ConnectionPool {
private static final Logger LOG = LoggerFactory.getLogger(ConnectionPool.class);
private static HikariDataSource dataSource;
static {
AppProperties appProperties = getAppProperties();
String jdbcUrl = appProperties.getProperty("db.url");
String username = appProperties.getProperty("db.username");
String password = appProperties.getProperty("db.password");
HikariConfig config = new HikariConfig();
config.setJdbcUrl(jdbcUrl);
config.setUsername(username);
config.setPassword(password);
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
dataSource = new HikariDataSource(config);
LOG.info("HikariDataSource inited,jdbcUrl: {},username: {}", jdbcUrl, username);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void closePool() {
if (dataSource != null) {
dataSource.close();
}
}
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
原始的进行数据库查询,需要先连接数据库->执行sql->得到结果->关闭connection等释放资源,这个过程消耗资源的开启连接数据库和关闭数据库连接这两步;
用上了数据池,例如HikariCP,初始化一个最大连接数给到HikariCP,程序加载类文件时,只需要连接一次数据库,用到获取数据库连接时,调用getConnection()即可,不用关心数据库连接数的管理,再程序中用完调用关闭连接,connection.close(),也是将当前连接交给数据库连接池来管理,例如给HikariCP来管理,比较有效,稳定的提升了数据库连接的效率。