SpringBoot2.2默认使用的连接池是HikariCP
Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
这里不进行两者的对比分析,单纯讲如何配置druid连接池
1.添加依赖
添加druid还有另一种,其它与下面相同,
com.alibaba
druid-spring-boot-starter
1.1.10
mysql
mysql-connector-java
2.配置application.yml(我使用的yml,所以以此为例来讲)
spring:
datasource:
druid:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/xxx?serverTimezone=GMT%2B8&characterEncoding=utf-8
username: xxx
password: xxx
#初始化时建立物理连接的个数
initial-size: 5
#最大连接池数量
max-active: 10
#最小连接池数量
min-idle: 5
#获取连接时最大等待时间,单位毫秒
max-wait: 60000
# 超过时间限制是否回收
removeAbandoned: true
# 当连接超过3分钟后会强制进行回收
removeAbandonedTimeout: 180
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
max-evictable-idle-time-millis: 60000
#用来检测连接是否有效的sql 必须是一个查询语句。mysql中为 select 'x', oracle中为 select 1 from dual
validation-query: select 'x'
# validation-query-timeout: 5000
#申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-borrow: false
#归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
test-on-return: false
test-while-idle: true
#通过connectProperties属性来打开mergeSql功能,慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#filters: #配置多个英文逗号分隔(统计,sql注入)
filters: stat,wall
#配置stat-view-servlet
stat-view-servlet:
#允许开启监控
enabled: true
#监控面板路径
url-pattern: /druid/*
3.配置配置类
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Configuration
public class DruidConfig {
private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);
@Value("${spring.datasource.druid.url}")
private String dbUrl;
@Value("${spring.datasource.druid.username}")
private String username;
@Value("${spring.datasource.druid.password}")
private String password;
@Value("${spring.datasource.druid.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.druid.initial-size}")
private int initialSize;
@Value("${spring.datasource.druid.max-active}")
private int maxActive;
@Value("${spring.datasource.druid.min-idle}")
private int minIdle;
@Value("${spring.datasource.druid.max-wait}")
private int maxWait;
@Value("${spring.datasource.druid.pool-prepared-statements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
private int maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.max-evictable-idle-time-millis}")
private int maxEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.validation-query}")
private String validationQuery;
@Value("${spring.datasource.druid.test-while-idle}")
private boolean testWhileIdle;
@Value("${spring.datasource.druid.test-on-borrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.druid.test-on-return}")
private boolean testOnReturn;
@Value("${spring.datasource.druid.filters}")
private String filters;
@Value("{spring.datasource.druid.connection-properties}")
private String connectionProperties;
/**
* Druid连接池配置
* @return
*/
//声明其为Bean实例
@Bean
public DruidDataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setMaxEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (Exception e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
/**
* JDBC操作配置
* @param dataSource
* @return
*/
@Bean(name = "dataOneTemplate")
public JdbcTemplate jdbcTemplate (@Autowired DruidDataSource dataSource){
return new JdbcTemplate(dataSource) ;
}
/**
* 配置 Druid 监控界面
*/
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean srb =
new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
//设置控制台管理用户
srb.addInitParameter("loginUsername","root");
srb.addInitParameter("loginPassword","root");
//是否可以重置数据。禁用HTML页面上的“Reset All”功能
srb.addInitParameter("resetEnable","false");
return srb;
}
@Bean
public FilterRegistrationBean statFilter(){
//创建过滤器
FilterRegistrationBean frb =
new FilterRegistrationBean(new WebStatFilter());
//设置过滤器过滤路径
frb.addUrlPatterns("/*");
//忽略过滤的形式
frb.addInitParameter("exclusions",
"*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return frb;
}
}
看到最后配置了自定义@Bean,statFilter, 还需要排除原来的statFilter的自动注入
在SpringBoot启动类中的@SpringBootApplication注解中添加:
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
4.为什么application.yml中要配置
# 超过时间限制是否回收 removeAbandoned: true # 当连接超过3分钟后会强制进行回收 removeAbandonedTimeout: 180
如果不进行此配置,在运行中有可能出现druid连接池超时回收的问题,导致没有空闲连接可用而报错
Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60009, active 10, max-active 10, creating 0
还可以再加一个配置
logAbandoned: true 关闭abandoned连接异常时输出到日志,不过这个影响性能
欢迎大家指正,交流学习