Java 数据库连接池介绍(7)--HikariCP 介绍
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;