Spring Boot使用hikari、druid、c3p0等数据库连接池详解
前言
截至Spring Boot V2.0为止,官方仅为下列数据库连接池产品提供了自动配置的支持。
# Hikari 数据库连接池
spring.datasource.hikari.*
# Tomcat 数据库连接池
spring.datasource.tomcat.*
# DBCP2 数据库连接池
spring.datasource.dbcp2.*
Hikari连接池
Spring Boot V2.0以后默认数据库连接池是Hikari,所以引用spring-boot-starter-parent依赖后就无需加专门依赖了。Hikari是速度最快、性能最强的连接池,但功能没有druid连接池齐全
spring:
datasource:
# jdbc配置
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
👉新建个测试类👉打断点Debug测试一下,看看Spring Boot V2.0以后默认数据库连接池到底是不是Hikari
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void datasource() {
System.out.println("当前使用连接池:"+dataSource.getClass());
}
}
测试结果证明:Spring Boot V2.0以后默认数据库连接池是Hikari,没毛病!

Hikari作为spring boot默认连接池,支持数据源自动配置,并自动将我们配置的连接池属性进行绑定,使之生效。具体可查看org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration类
🆗,我们配置几个Hikari连接池的私有属性,更多属性配置可查看👉Hikari
spring:
datasource:
# jdbc配置
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
# hikari连接池配置
hikari:
maximum-pool-size: 30
minimum-idle: 1
idle-timeout: 45000
max-lifetime: 120000
接着,打断点Debug测试一下,看看能不能自动帮我们将配置的连接池属性绑定上
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void datasource() {
System.out.println("当前使用连接池:"+dataSource.getClass());
}
}
测试结果证明:spring boot会自动帮我们绑定👉配置的Hikari连接池属性

Druid连接池
Druid作为国内使用最广泛的数据库连接池产品,但Spring Boot官方貌似也没有对Druid提供自动配置的支持。所以使用Druid还需要我们手动装配和实现属性绑定
添加druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
🆗,接下来配置Druid连接池相关属性,更多属性配置可查看👉DruidDataSource配置属性列表
server:
port: 8080
servlet:
context-path: /o2o
spring:
datasource:
# jdbc配置
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding&useSSL=false&serverTimezone=UTC
# 指定数据库连接池类型,不指定则默认使用hikari
type: com.alibaba.druid.pool.DruidDataSource
# druid连接池配置
initialSize: 1 #初始化大小
maxActive: 20 #最大连接数
minIdle: 1 #最小连接数
maxWait: 60000 #获取连接等待超时的时间
testOnBorrow: true #连接时是否检查连接可用性
testOnReturn: false #归还连接时是否检查连接可用性
接着新建一个测试类,打断点Debug测试一下,看看能不能自动帮我们将配置的连接池属性绑定上
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void datasource() {
System.out.println("当前使用连接池:"+dataSource.getClass());
}
}
测试结果证明:我们配置的那几个属性使用的还是默认值。即spring boot并没有将我们配置Druid私有属性绑定到DruidDataSource的对应属性中。

首先,我们我们在yml属性文件中指定连接池类型后,spring boot就会自动帮我们创建DruidDataSource对象。尴尬的是👉你帮我创建DruidDataSource对象,但你又不帮我将配置的Druid私有属性绑定进去,那我还要你帮我干嘛!
所以这时候,我们就要自己写一个配置类,来专门配置Druid。内容如下
// 类上标注了@Configuration注解,意味着它是一个IoC容器配置类
@Configuration
public class DruidConfiguration {
// 标注@Bean后表明返回对象为一个bean
@Bean(name = "dataSource")
// 将yml/properties属性文件中指定前缀的属性绑定到返回对象对应的属性中
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
//return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
}
}
🆗,接着我们在打断点Debug测试一下,发现yml属性文件中配置的Druid私有属性已成功绑定到DruidDataSource的对应属性中

Druid(新版starter)连接池
前面说过,spring boot没有对druid提供自动配置支持,需要我们手动编写配置类进行配置。当后面不知道什么情况,搞出了个druid-spring-boot-starter,可以快速的在Spring Boot项目中集成Druid连接池和监控。
添加druid-spring-boot-starter依赖(1.1.1版本以上),帮助我们在spring boot项目中轻松集成Druid数据库连接池和监控(即:自动将我们配置的属性绑定到DruidDataSource对应的属性中)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
Druid Spring Boot Starter配置属性的名称完全遵从druid,如果没有配置则使用默认值,更多属性配置可查看👉DruidDataSource配置属性列表,(driver-class-name属性可以不配置,因为druid可以根具url自动推测出来)
server:
port: 8080 #端口号,默认值为8080
servlet:
context-path: /o2o #应用上下文路径或访问根路径
# 数据源
spring:
datasource:
druid:
# JDBC配置
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
# 连接池配置
initial-size: 1 #初始化大小
max-active: 20 #最大连接数
min-idle: 1 #最小连接数
max-wait: 60000 # 获取连接时最大等待时间,单位毫秒
test-on-borrow: true #连接时是否检查连接可用性
test-on-return: false #归还连接时是否检查连接可用性
test-while-idle: true
配置好连接池后,打断点Debug查看一下,spring boot有没有帮我们将配置的属性绑定到DruidDataSource中。在第20行代码中打个断点debug一下,查看配置的属性有没有被绑定到DruidDataSource中
package com.cd.springbootdemo1.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void datasource() {
System.out.println(dataSource.getClass());
}
}
👉测试结果:yml属性文件中配置的Druid私有属性有绑定到DruidDataSource的对应属性中

C3P0连接池(1
c3p0连接池也不支持自动配置,跟druid一样,需要我们手动编写配置类进行配置
添加c3p0依赖
<!--c3p0数据连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
配置c3p0连接池相关属性,且c3p0使用的数据库用户名属性是user而非username。更多配置属性可参考👉c3p0配置属性
server:
port: 8080 #tomcat端口号
servlet:
context-path: /o2o #项目根路径/应用上下文路径
# dataSource数据源
spring:
datasource:
#jdbc配置
driverClass: com.mysql.cj.jdbc.Driver #数据库驱动类
user: root #数据库用户名
password: root #数据库用户密码
jdbcUrl: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC #数据库连接URL
#c3cp0连接池
type: com.mchange.v2.c3p0.ComboPooledDataSource #指定自定义连接池类型,不指定则默认使用hikari
dataSourceName: dataSource
initialPoolSize: 1 #连接池初始化连接数
minPoolSize: 1 #连接池最小连接数
maxPoolSize: 20 #连接池最大连接数
autoCommitOnClose: false #关闭连接后不自动提交
checkoutTimeout: 10000 #连接超时时间
maxIdleTime: 1800000 #连接的最大空闲时间,超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接
acquireRetryAttempts: 2 #连接池在获取连接失败后允许重试次数
编写c3p0连接池配置类,创建ComboPooledDataSource Bean,并将yml属性文件中指定前缀的属性绑定进bean实例中
@Configuration //类上标注了@Configuration注解,意味着它是一个IoC容器配置类
public class DataSourceConfiguration {
@Bean //标注@Bean后表明返回对象为
@Primary //primary将当前数据库连接池作为默认数据库连接池
@ConfigurationProperties(prefix = "spring.datasource") //将yml属性文件中指定前缀的属性绑定进bean实例中
public DataSource dataSource(){
return new ComboPooledDataSource();
//return DataSourceBuilder.create().type(return DataSourceBuilder.create().type(com.mchange.v2.c3p0.ComboPooledDataSource.class).build();.class).build();
}
}
创建测试类,打断点Debug查看yml属性文件中配置的c3p0连接池属性是否有绑定到连接池对象对应属性中
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataSourceTest {
@Autowired
private DataSource dataSource;
@Test
public void datasource() {
System.out.println("当前使用连接池:"+dataSource.getClass());
}
}
测试结果:✌

C3P0连接池(2
c3p0连接池配置,除了上述方式外,我见过一些人还喜欢像配置其他任何Spring Bean一样直接进行配置,具体如下
<!--c3p0数据连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
server:
port: 8080 #tomcat端口号
servlet:
context-path: /o2o #应用上下文路径 或 项目根路径
# DataSource
driverClass: com.mysql.cj.jdbc.Driver
user: root
password: root
jdbcUrl: jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding&useSSL=false&serverTimezone=UTC
@Configuration
public class C3P0Configuration {
@Value("${driverClass}")
private String driverClassName;
@Value("${user}")
private String username;
@Value("${password}")
private String password;
@Value("${jdbcUrl}")
private String url;
/**
* 生成c3p0连接池的bean
* @return
* @throws PropertyVetoException
*/
@Bean(name = "dataSource")
public ComboPooledDataSource createDataSource() throws PropertyVetoException {
//创建c3p0连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
/*基本配置*/
dataSource.setDriverClass(driverClassName); //数据库驱动类
dataSource.setUser(username); //数据库用户名
dataSource.setPassword(password); //数据库用户密码
dataSource.setJdbcUrl(url);//数据库连接URL
/*配置c3p0连接池的私有属性*/
dataSource.setMaxPoolSize(30); //连接池最大连接数
dataSource.setMinPoolSize(10); //连接池最小连接数
dataSource.setAutoCommitOnClose(false); //关闭连接后不自动提交
dataSource.setCheckoutTimeout(10000); //连接超时时间
dataSource.setAcquireRetryAttempts(2); //连接失败允许重试次数
//返回连接池对象
return dataSource;
}
}
😄😄 这里我就不测试了,测试方式也上面的雷同
扩展
更多推荐



所有评论(0)