SpringBoot--集成Druid連接池


Druid是什么?

Druid是Java語言中最好的數據庫連接池。Druid能夠提供強大的監控和擴展功能。

優點:

  •  可以監控數據庫訪問性能,Druid內置提供了一個功能強大的StatFilter插件,能夠詳細統計SQL的執行性能,這對於線上分析數據庫訪問性能有幫助。
  •  替換DBCP和C3P0。Druid提供了一個高效、功能強大、可擴展性好的數據庫連接池。
  •  數據庫密碼加密。直接把數據庫密碼寫在配置文件中,這是不好的行為,容易導致安全問題。DruidDruiver和DruidDataSource都支持PasswordCallback。
  • SQL執行日志,Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應的LogFilter,監控你應用的數據庫訪問情況。
  • 擴展JDBC,如果你要對JDBC層有編程的需求,可以通過Druid提供的Filter-Chain機制,很方便編寫JDBC層的擴展插件

SpringBoot集成Druid

1. 引入maven依賴

<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.20</version>
</dependency>

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
</dependency>

2.在 application.yml 文件中加入數據庫的配置(屬性名的值和冒號中間必須有空格!):

spring:
  datasource:
    #mysql 配置
    dbType: mysql
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    # 驅動配置信息
    type: com.alibaba.druid.pool.DruidDataSource
    # 連接池的配置信息:初始化大小,最小,最大
    initialSize: 1
    minIdle: 1
    maxActive: 3
    # 配置獲取連接等待超時的時間
    maxWait: 60000
    # 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一個連接在池中最小生存的時間,單位是毫秒
    minEvictableIdleTimeMillis: 30000
    #驗證庫是否正常sql
    validationQuery: select 'x'
    #空閑時驗證,防止連接斷開
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打開PSCache,並且指定每個連接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用於防火牆
    filters: stat,wall,slf4j
    # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    

3.加入Druid配置類:

由於目前Spring Boot中默認支持的連接池只有 dbcp、dbcp2、 tomcat、hikari 連接池,Druid 暫時不在Spring Boot 中的直接支持,故需要進行配置信息的定制:
新建druid包,加入DruidDBConfig 實現類,類中的屬性值一定要和 application.yal文件中對應屬性保持一致

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
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.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;

@Configuration
public class DruidDBConfig {
    private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);

    @Bean
    public ServletRegistrationBean druidServlet() {
        logger.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名單
        servletRegistrationBean.addInitParameter("allow", "");
        // IP黑名單(共同存在時,deny優先於allow)
        servletRegistrationBean.addInitParameter("deny", "");
        //控制台管理用戶
        servletRegistrationBean.addInitParameter("loginUsername", "");
        servletRegistrationBean.addInitParameter("loginPassword", "");
        //是否能夠重置數據 禁用HTML頁面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

    // 解決 spring.datasource.filters=stat,wall,log4j 無法正常注冊進去
    //使用@ConfigurationProperties替代@Value("${spring.datasource.url}")注解
    @ConfigurationProperties(prefix = "spring.datasource")
    @Data //lombok注解,可以省略setter、getter方法 class DataSourceProperties{
private String dbType;
private String url; private String username; private String password; private String driverClassName; private int initialSize; private int minIdle; private int maxActive; private int maxWait; private int timeBetweenEvictionRunsMillis; private int minEvictableIdleTimeMillis; private String validationQuery; private boolean testWhileIdle; private boolean testOnBorrow; private boolean testOnReturn; private boolean poolPreparedStatements; private int maxPoolPreparedStatementPerConnectionSize; private String filters; private String connectionProperties; @Bean //聲明其為Bean實例 @Primary //表示這里定義的DataSource將覆蓋其他來源的DataSource。 public DataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); datasource.setDbType(dbType); datasource.setUrl(url); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); //configuration datasource.setInitialSize(initialSize); datasource.setMinIdle(minIdle); datasource.setMaxActive(maxActive); datasource.setMaxWait(maxWait); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setValidationQuery(validationQuery); datasource.setTestWhileIdle(testWhileIdle); datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnReturn(testOnReturn); datasource.setPoolPreparedStatements(poolPreparedStatements); datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); try { datasource.setFilters(filters); } catch (SQLException e) { logger.error("druid configuration initialization filter : {}", e); } datasource.setConnectionProperties(connectionProperties); return datasource; } } }

 4.運行項目

啟動springboot項目,訪問 http://localhost:8080/druid/index.html 直接登錄訪問 Druid 的后台。

 5.問題小結

### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: dbType not support : null, url null] with root cause 
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: dbType not support : null, url null
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84)
    at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82)

解決方法:application.yml文件缺少dbType屬性,url配置文件和類中的名稱不一致,導致值沒有注入。

spring:
datasource:
#mysql 配置
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
# 驅動配置信息
type: com.alibaba.druid.pool.DruidDataSource
dbType: mysql
# 連接池的配置信息:初始化大小,最小,最大
initialSize: 1
minIdle: 1
maxActive: 3
# 配置獲取連接等待超時的時間
maxWait: 60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一個連接在池中最小生存的時間,單位是毫秒
minEvictableIdleTimeMillis: 30000
#驗證庫是否正常sql
validationQuery: select 'x'
#空閑時驗證,防止連接斷開
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打開PSCache,並且指定每個連接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用於防火牆
filters: stat,wall,slf4j
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM