SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置
在项目中,数据库连接池基本是必不可少的组件。在目前数据库连接池的选型中,主要是
在Spring Boot 2.X 版本,默认采用 HikariCP 连接池。而阿里大规模采用 Druid 。下面介绍在SpringBoot中使用HikariCP、Druid连接池。
1、HikariCP数据库连接池
1.1 HikariCP单数据源配置
1.1.1 pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>HikariCP-Boot</artifactId>
<dependencies>
<!-- 实现对数据库连接池的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- 写单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
- 无需主动引入 HikariCP 的依赖。因为在 Spring Boot 2.X 中,
spring-boot-starter-jdbc
默认引入com.zaxxer.HikariCP
依赖。
1.1.2 yml配置
server:
port: 7890
spring:
# datasource 数据源配置内容,对应 DataSourceProperties 配置属性类
datasource:
url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root # 数据库账号
password: root # 数据库密码
# HikariCP 自定义配置,对应 HikariConfig 配置属性类
hikari:
minimum-idle: 10 # 池中维护的最小空闲连接数,默认为 10 个。
maximum-pool-size: 10 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
- 在
spring.datasource
配置项下,我们可以添加数据源的通用配置。 - 在
spring.datasource.hikari
配置项下,我们可以添加 HikariCP 连接池的自定义配置。然后DataSourceConfiguration.Hikari
会自动化配置 HikariCP 连接池。
1.1.3 主启动类
package com.yyds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@SpringBootApplication
public class ApplicationBak implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(ApplicationBak.class);
@Autowired
private DataSource dataSource;
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(ApplicationBak.class, args);
}
@Override
public void run(String... args) {
try (Connection conn = dataSource.getConnection()) {
// 这里,可以做点什么
logger.info("[run][获得连接:{}]", conn);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
通过实现 CommandLineRunner接口,应用启动完成后,回调 #run(String... args)
方法,输出 Connection 信息。
1.2 HikariCP多数据源配置
1.2.1 pom文件
如1.2.1所示。
1.2.2 yml配置
spring:
# datasource 数据源配置内容
datasource:
# 订单数据源配置
orders:
url: jdbc:mysql://127.0.0.1:3306/test_orders?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
# HikariCP 自定义配置,对应 HikariConfig 配置属性类
hikari:
minimum-idle: 20 # 池中维护的最小空闲连接数,默认为 10 个。
maximum-pool-size: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
# 用户数据源配置
users:
url: jdbc:mysql://127.0.0.1:3306/test_users?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
# HikariCP 自定义配置,对应 HikariConfig 配置属性类
hikari:
minimum-idle: 15 # 池中维护的最小空闲连接数,默认为 10 个。
maximum-pool-size: 15 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
1.2.3 主启动类
package com.yyds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@SpringBootApplication
public class Application implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(Application.class);
@Resource(name = "ordersDataSource")
private DataSource ordersDataSource;
@Resource(name = "usersDataSource")
private DataSource usersDataSource;
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
// orders 数据源
try (Connection conn = ordersDataSource.getConnection()) {
// 这里,可以做点什么
logger.info("[run][ordersDataSource 获得连接:{}]", conn);
} catch (SQLException e) {
throw new RuntimeException(e);
}
// users 数据源
try (Connection conn = usersDataSource.getConnection()) {
// 这里,可以做点什么
logger.info("[run][usersDataSource 获得连接:{}]", conn);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
1.2.4 配置类
package com.yyds.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
/**
* 创建 orders 数据源的配置对象
*/
@Primary
@Bean(name = "ordersDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.orders") // 读取 spring.datasource.orders 配置到 DataSourceProperties 对象
public DataSourceProperties ordersDataSourceProperties() {
return new DataSourceProperties();
}
/**
* 创建 orders 数据源
*/
@Bean(name = "ordersDataSource")
@ConfigurationProperties(prefix = "spring.datasource.orders.hikari") // 读取 spring.datasource.orders 配置到 HikariDataSource 对象
public DataSource ordersDataSource() {
// <1.1> 获得 DataSourceProperties 对象
DataSourceProperties properties = this.ordersDataSourceProperties();
// <1.2> 创建 HikariDataSource 对象
return createHikariDataSource(properties);
}
/**
* 创建 users 数据源的配置对象
*/
@Bean(name = "usersDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.users") // 读取 spring.datasource.users 配置到 DataSourceProperties 对象
public DataSourceProperties usersDataSourceProperties() {
return new DataSourceProperties();
}
/**
* 创建 users 数据源
*/
@Bean(name = "usersDataSource")
@ConfigurationProperties(prefix = "spring.datasource.users.hikari")
public DataSource usersDataSource() {
// 获得 DataSourceProperties 对象
DataSourceProperties properties = this.usersDataSourceProperties();
// 创建 HikariDataSource 对象
return createHikariDataSource(properties);
}
private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {
// 创建 HikariDataSource 对象
HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
// 设置线程池名
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
ordersDataSourceProperties()方法,创建orders数据源
的DataSourceProperties配置对象。
-
@Primary注解,保证项目中有一个主的DataSourceProperties Bean。
-
加上 @Bean(name = “ordersDataSourceProperties”)注解,会创建一个名字位ordersDataSourceProperties的DataSourceProperties Bean
-
@ConfigurationProperties(prefix = “spring.datasource.orders”)注解,会将spring.datasource.orders配置项,逐个属性赋值给DataSourceProperties Bean
ordersDataSource()方法,创建orders
数据源。
-
DataSourceProperties properties = this.ordersDataSourceProperties();
获取orders数据源的DataSourceProperties配置对象
-
createHikariDataSource()方法创建HikariDataSource对象,这样,
"spring.datasource.orders"
配置项,逐个属性赋值给 HikariDataSource Bean 。 -
搭配上
@Bean(name = "ordersDataSource")
注解,会创建一个名字为"ordersDataSource"
的 HikariDataSource Bean 。 -
@ConfigurationProperties(prefix = "spring.datasource.orders.hikari")
注解,会将 HikariCP 的"spring.datasource.orders.hikari"
自定义配置项,逐个属性赋值给 HikariDataSource Bean 。
2、Druid数据库连接池
2.1 Druid单数据源配置
2.1.1 pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Druid-Boot</artifactId>
<dependencies>
<!-- 保证 Spring JDBC 的依赖健全 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 实现对 Druid 连接池的自动化配置 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- 实现对 Spring MVC 的自动化配置,因为我们需要看看 Druid 的监控功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 方便等会写单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.1.2 yml配置
spring:
# datasource 数据源配置内容,对应 DataSourceProperties 配置属性类
datasource:
url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root # 数据库账号
password: root # 数据库密码
type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
# Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
druid:
min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
filter:
stat: # 配置 StatFilter ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
log-slow-sql: true # 开启慢查询记录
slow-sql-millis: 5000 # 慢 SQL 的标准,单位:毫秒
stat-view-servlet: # 配置 StatViewServlet ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
enabled: true # 是否开启 StatViewServlet
login-username: root # 账号
login-password: root # 密码
2.1.3主启动类
package com.yyds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.sql.DataSource;
@SpringBootApplication
public class ApplicationBak implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(ApplicationBak.class);
@Autowired
private DataSource dataSource;
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(ApplicationBak.class, args);
}
@Override
public void run(String... args) {
logger.info("[run][获得数据源:{}]", dataSource.getClass());
}
}
2.1.4 监控
因为做了如下操作:
- 通过
spring.datasource.filter.stat
配置了 StatFilter ,统计监控信息。 - 通过
spring.datasource.filter.stat-view-servlet
配置了 StatViewServlet ,提供监控信息的展示的 html 页面和 JSON API
所以我们在启动项目后,访问 http://127.0.0.1:8080/druid
地址,账户密码为配置的root,可以看到监控 html 页面。
- 在界面的顶部,提供了数据源、SQL 监控、SQL 防火墙等功能。
- 每个界面上,可以通过 [View JSON API]获得数据的来源。
- 因为监控信息是存储在 JVM 内存中,在 JVM 进程重启时,信息将会丢失。如果我们希望持久化到 MySQL、Elasticsearch、HBase 等存储器中,可以通过 StatViewServlet 提供的 JSON API 接口,采集监控信息。
Druid 的文档:https://github.com/alibaba/druid/wiki/
。
2.2 Druid多数据源配置
2.2.1 pom文件
如2.1.1
2.2.2 yml配置
spring:
# datasource 数据源配置内容
datasource:
# 订单数据源配置
orders:
url: jdbc:mysql://127.0.0.1:3306/test_orders?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password:
type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
# Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
# 用户数据源配置
users:
url: jdbc:mysql://127.0.0.1:3306/test_users?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
# Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
# Druid 自定已配置
druid:
# 过滤器配置
filter:
stat: # 配置 StatFilter ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
log-slow-sql: true # 开启慢查询记录
slow-sql-millis: 5000 # 慢 SQL 的标准,单位:毫秒
# StatViewServlet 配置
stat-view-servlet: # 配置 StatViewServlet ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
enabled: true # 是否开启 StatViewServlet
login-username: root # 账号
login-password: root # 密码
2.2.3主启动类
package com.yyds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.Resource;
import javax.sql.DataSource;
@SpringBootApplication
public class Application implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(Application.class);
@Resource(name = "ordersDataSource")
private DataSource ordersDataSource;
@Resource(name = "usersDataSource")
private DataSource usersDataSource;
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
// orders 数据源
logger.info("[run][获得数据源:{}]", ordersDataSource.getClass());
// users 数据源
logger.info("[run][获得数据源:{}]", usersDataSource.getClass());
}
}
2.2.4 配置类
package com.yyds.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 {
/**
* 创建 orders 数据源
*/
@Primary
@Bean(name = "ordersDataSource")
@ConfigurationProperties(prefix = "spring.datasource.orders")
public DataSource ordersDataSource() {
return DruidDataSourceBuilder.create().build();
}
/**
* 创建 users 数据源
*/
@Bean(name = "usersDataSource")
@ConfigurationProperties(prefix = "spring.datasource.users")
public DataSource usersDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
可以看到数据源加载成功。