HikariCP 是一個快速、簡單、可靠的 JDBC 連接池,在性能上做了很多優化,是目前最快的數據庫連接池;本文主要介紹 HikariCP 的基本使用,文中使用到的軟件版本:Java 1.8.0_191、HikariCP 4.0.3、Spring Boot 2.3.12.RELEASE。
1、配置參數
HikariCP 所有時間相關的參數單位都為 ms。
1.1、基本配置
參數 | 默認值 | 描述 |
dataSourceClassName | none | 驅動里面數據源的類名稱;不支持 XA數據源,各數據源對應的數據源類名可參見 ”2、數據源類名“ |
jdbcUrl | none | 連接 url;該參數與 dataSourceClassName 設置一個即可 |
username | none | 用戶名 |
password | none | 密碼 |
1.2、常用配置
參數 | 默認值 | 描述 |
autoCommit | true | 連接返回連接池時,是否自動提交事務 |
connectionTimeout | 30000 | 從連接池獲取連接的最大超時時間 |
idleTimeout | 60000 | 空閑連接存活的最大時間,當空閑連接數>minimumIdle 且 連接的空閑狀態時間>idleTimeout 時,將把該連接從連接池中刪除;只有當 minimumIdle < maximumPoolSize 時,該設置才生效;0 表示永不超時 |
keepaliveTime | 0 | 保持空閑連接可用的檢測頻率,單位:ms;0 表示不檢測 |
maxLifetime | 1800000 | 連接存活的最大時間;0 表示沒有限制 |
connectionTestQuery | none | 連接檢測的查詢語句;如果驅動支持 JDBC 4,強烈建議不要設置此參數 |
minimumIdle | same as maximumPoolSize | 最小空閑連接數;為了提高性能,建議不要設置此參數,使連接池為固定大小 |
maximumPoolSize | 10 | 最大連接數 |
metricRegistry | none | 該參數僅通過編程配置或 IoC 容器可用;該參數用於指定池使用的 Codahale/Dropwizard MetricRegistry實例來記錄各種指標。 |
healthCheckRegistry | none | 該參數僅通過編程配置或 IoC 容器可用;該參數用於指定池使用的 Codahale/Dropwizard HealthCheckRegistry實例來記錄健康信息。 |
poolName | auto-generated | 連接池名稱 |
1.3、不常用配置
參數 | 默認值 | 描述 |
initializationFailTimeout | 1 | 啟動連接池時不能成功初始化連接,是否快速失敗。>0 時,會嘗試獲取連接。如果獲取時間超過指定時長(connectionTimeout + initializationFailTimeout),不會開啟連接池,並拋出異常。=0 時,會嘗試獲取並驗證連接。如果獲取成功但驗證失敗則不開啟池,但是如果獲取失敗還是會開啟池。<0 時,直接啟動連接池,不進行初始化連接嘗試。 |
isolateInternalQueries | false | 是否在事務中隔離 HikariCP 自己的查詢;autoCommit 為 false 時,該設置生效 |
allowPoolSuspension | false | 是否允許通過 JMX 掛起和恢復連接池;掛起時獲取連接不會超時,知道連接池恢復 |
readOnly | false | 連接是否只讀 |
registerMbeans | false | 是否開啟 JMX |
catalog | driver default | 默認的數據庫 catalog |
connectionInitSql | none | 連接池初始化后執行的 SQL |
driverClassName | none | 驅動類名;HikariCP 會嘗試通過 jdbcUrl 來確定 driverClassName,但對一些老的驅動必須指定 driverClassName;可以忽略該配置除非報 "the driver was not found" 的錯誤。 |
transactionIsolation | driver default | 默認的事務隔離級別 |
validationTimeout | 5000 | 連接檢測的超時時間;必須大於 connectionTimeout,最小允許的值為 250 |
leakDetectionThreshold | 0 | 連接可以被借出多久;超過該時間將打印連接可能泄露的日志,最小允許的值為 2000,單位 ms |
dataSource | none | 指定數據源;此參數僅通過編程配置或 IoC 容器可用,當設置此參數,dataSourceClassName 和所有 DataSource- 相關的屬性將被忽略。 |
schema | driver default | 默認的數據庫 schema |
threadFactory | none | 指定連接池用於創建線程的 java.util.concurrent.ThreadFactory 實例;此參數僅通過編程配置或 IoC 容器可用 |
scheduledExecutor | none | 指定連接池用於執行定時任務的 java.util.concurrent.ScheduledExecutorService 實例;此參數僅通過編程配置或 IoC 容器可用 |
詳細的配置說明可參考官網文檔:https://github.com/brettwooldridge/HikariCP
2、數據源類名
HikariCP 建議使用 dataSourceClassName 代替 jdbcUrl,但是兩個都是支持的。
注:Spring Boot 基於自動配置,使用 jdbcUrl。
MySQL 的 DataSource 不支持網絡超時,使用 jdbcUrl 代替。
常用數據庫的 JDBC 數據源類名如下:
Database | Driver | DataSource class |
---|---|---|
Apache Derby | Derby | org.apache.derby.jdbc.ClientDataSource |
Firebird | Jaybird | org.firebirdsql.ds.FBSimpleDataSource |
H2 | H2 | org.h2.jdbcx.JdbcDataSource |
HSQLDB | HSQLDB | org.hsqldb.jdbc.JDBCDataSource |
IBM DB2 | IBM JCC | com.ibm.db2.jcc.DB2SimpleDataSource |
IBM Informix | IBM Informix | com.informix.jdbcx.IfxDataSource |
MS SQL Server | Microsoft | com.microsoft.sqlserver.jdbc.SQLServerDataSource |
Connector/J | ||
MariaDB | MariaDB | org.mariadb.jdbc.MariaDbDataSource |
Oracle | Oracle | oracle.jdbc.pool.OracleDataSource |
OrientDB | OrientDB | com.orientechnologies.orient.jdbc.OrientDataSource |
PostgreSQL | pgjdbc-ng | com.impossibl.postgres.jdbc.PGDataSource |
PostgreSQL | PostgreSQL | org.postgresql.ds.PGSimpleDataSource |
SAP MaxDB | SAP | com.sap.dbtech.jdbc.DriverSapDB |
SQLite | xerial | org.sqlite.SQLiteDataSource |
SyBase | jConnect | com.sybase.jdbc4.jdbc.SybDataSource |
3、使用
3.1、直接使用
3.1.1、引入依賴
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>4.0.3</version> </dependency>
3.1.2、使用例子
package com.abc.demo.general.dbpool; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class HikariCPCase { private static Logger logger = LoggerFactory.getLogger(HikariCPCase.class); /** * 使用 dataSourceClassName */ @Test public void test1() { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setPoolName("HikariCP 連接池"); hikariConfig.setDataSourceClassName("oracle.jdbc.pool.OracleDataSource"); hikariConfig.addDataSourceProperty("user", "test"); hikariConfig.addDataSourceProperty("password", "123456"); hikariConfig.addDataSourceProperty("url", "jdbc:oracle:thin:@10.49.196.10:1521:test"); hikariConfig.setMaximumPoolSize(15); HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig); Connection connection = null; try { connection = hikariDataSource.getConnection(); Statement st = connection.createStatement(); ResultSet rs = st.executeQuery("select * from v$version"); if (rs.next()) { logger.info(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { close(connection); } //實際使用中一般是在應用啟動時初始化數據源,應用從數據源中獲取連接;並不會關閉數據源。 hikariDataSource.close(); } /** * 使用jdbc-url */ @Test public void test2() { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setPoolName("HikariCP 連接池"); hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver"); hikariConfig.setJdbcUrl("jdbc:mysql://10.49.196.11:3306/mydb?useUnicode=true&characterEncoding=UTF-8"); hikariConfig.setUsername("root"); hikariConfig.setPassword("123456"); hikariConfig.setMinimumIdle(2); hikariConfig.setMaximumPoolSize(10); HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig); Connection connection = null; try { connection = hikariDataSource.getConnection(); Statement st = connection.createStatement(); ResultSet rs = st.executeQuery("select version()"); if (rs.next()) { logger.info(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { close(connection); } //實際使用中一般是在應用啟動時初始化數據源,應用從數據源中獲取連接;並不會關閉數據源。 hikariDataSource.close(); } private static void close(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
3.2、在 SpringBoot 中使用
3.2.1、引入依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>4.0.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
3.2.2、單數據源
application.yml 配置:
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://10.140.9.11:3306/mydb?useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 #type: com.zaxxer.hikari.HikariDataSource hikari: maximum-pool-size: 15
使用:
@Autowired private DataSource dataSource;
3.2.3、多數據源
application.yml 配置:
spring: datasource: hikari: db1: pool-name: 連接池1 driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://10.49.196.11:3306/mydb?useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 maximum-pool-size: 15 db2: pool-name: 連接池2 driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://10.49.196.12:3306/mydb?useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 maximum-pool-size: 15
數據源配置類:
package com.abc.demo.config; import com.zaxxer.hikari.HikariDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Primary @Bean(name = "dataSource1") @ConfigurationProperties("spring.datasource.hikari.db1") public DataSource dataSourceOne(){ return DataSourceBuilder.create().type(HikariDataSource.class).build(); } @Bean(name = "dataSource2") @ConfigurationProperties("spring.datasource.hikari.db2") public DataSource dataSourceTwo(){ return DataSourceBuilder.create().type(HikariDataSource.class).build(); } }
使用:
@Autowired @Qualifier("dataSource1") private DataSource dataSource1; @Autowired @Qualifier("dataSource2") private DataSource dataSource2;