SpringBoot整合Druid


最近一直在折騰springboot,也根據需要整合了一些好用的庫,mybatis作為持續層數據操作,也想用一下大名鼎鼎的Druid來做連接池和數據庫監控服務。於是摸索了一下午,整理出這篇小文,希望能幫助到同道,也給自己做個記錄反思。

  • 1.關於Druid

Druid是阿里團隊開源的高性能數據庫連接池,國內使用廣泛,特別是在監控sql和數據庫性能方面非常強大。

連接池能有效節省數據庫連接消耗,且對高寫入、實時性要求高的業務非常合適。

  • 2.引入依賴到pom.xml中。
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid-spring-boot-starter</artifactId>
   <version>1.1.10</version>
</dependency>

  • 3.然后在application.yml中設置相關配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test_go?characterEncoding=UTF-8&useSSL=false
    username: xxx
    password: xxxxxx
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 30000
      filters: stat
      async-init: true

其中最重要的是

type: com.alibaba.druid.pool.DruidDataSource

這樣就不會使用Springboot默認的連接池Hikari。

由於SpringBoot沒法生效寫在yml文件中的配置,需要單獨編寫Bean文件來加載。

  • 4.定義Druid配置類。
package com.tony.testspringboot.config;


import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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 DruidConfig {
    private Logger logger = LoggerFactory.getLogger(DruidConfig.class);

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.test-druid.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.druid.initial-size}")
    private int initialSize;

    @Value("${spring.datasource.druid.min-idle}")
    private int minIdle;

    @Value("${spring.datasource.druid.max-active}")
    private int maxActive;

    @Value("${spring.datasource.druid.max-wait}")
    private int maxWait;

    @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.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.pool-prepared-statements}")
    private boolean poolPreparedStatements;

    @Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
    private int maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.druid.filters}")
    private String filters;

    @Bean
    @Primary
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();

        datasource.setUrl(this.dbUrl);
        datasource.setUsername(this.username);
        datasource.setPassword(this.password);
        datasource.setDriverClassName(this.driverClassName);

        // configuration
        datasource.setInitialSize(this.initialSize);
        datasource.setMinIdle(this.minIdle);
        datasource.setMaxActive(this.maxActive);
        datasource.setMaxWait(this.maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);
        datasource.setTestWhileIdle(this.testWhileIdle);
        datasource.setTestOnBorrow(this.testOnBorrow);
        datasource.setTestOnReturn(this.testOnReturn);
        datasource.setPoolPreparedStatements(this.poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(this.maxPoolPreparedStatementPerConnectionSize);

        try {
            datasource.setFilters(this.filters);
        } catch (SQLException e) {
            logger.error("druid configuration init fail!");
        }

        return datasource;
    }
}

如此即可讓配置的參數生效並作為首選的DataSource進行使用。

5.在Controller中測試。

可以使用JdbcTemplate來進行查詢。
測試代碼如下所示:

@RequestMapping(value = "/hey", method = RequestMethod.GET)
public ResultResponse testDruid() {

    String sql = "SELECT mobile FROM user WHERE id = ?";

    String mobile = jdbcTemplate.queryForObject(sql, new Object[]{1}, String.class);

    return new ResultResponse(201, "hey" + mobile);
}

PS: ResultResponse是我項目中封裝的通用response對象。

關於多數據源參數的設置。

只需要在yml(application.yml)中設置即可,格式如下:

datasource:
    one-source:
      url: jdbc:mysql://127.0.0.1:3306/test_go?characterEncoding=UTF-8&useSSL=false
      username: xxxx1
      password: xxxx
      driver-class-name: com.mysql.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
    two-source:
      url: jdbc:mysql://127.0.0.1:3306/demo2?characterEncoding=UTF-8&useSSL=false
      username: xxxx
      password: 1xxxxxx
      driver-class-name: com.mysql.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
    ...

使用的時候也遵循這個結構,如要獲取第一個數據源的url配置則在DruidConfig.java文件中的相應項的@Value中這樣寫:

@Value("${spring.datasource.one-source.url}")
private String dbUrl;
  • 6.配置數據庫監控。

a) 先在application.yml中增加如下配置:

druid:
   .....
   # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
   connection-properties: druid.stat.mergeSql=true;druid.stat.SlowSqlMills=5000
   # 監控后台的配置,如登錄賬號和密碼等
   monitor:
     allow: 127.0.0.1
     loginUsername: admin
     loginPassword: admin

b)單獨編寫DruidMonitorConfiguration類。

public class DruidMonitorConfiguration {

    @Value("${spring.datasource.druid.monitor.allow}")
    private String allow;
//    @Value("${spring.datasource.druid.monitor.deny}")
//    private String deny;
    @Value("${spring.datasource.druid.monitor.loginUsername}")
    private String loginUsername;
    @Value("${spring.datasource.druid.monitor.loginPassword}")
    private String loginPassword;
    @Value("${spring.datasource.druid.monitor.resetEnable")
    private String resetEnable;
    @Bean
    public ServletRegistrationBean druidStatViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        servletRegistrationBean.addInitParameter("allow", this.allow);
//        servletRegistrationBean.addInitParameter("deny", this.deny);
        servletRegistrationBean.addInitParameter("loginUsername", this.loginUsername);
        servletRegistrationBean.addInitParameter("loginPassword", this.loginPassword);
        servletRegistrationBean.addInitParameter("resetEnable", this.resetEnable);
        return servletRegistrationBean;
    }

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

}

訪問方法就是:http://project-name.com/druid/login.html

驗證登錄即可。整個監控功能十分強大,有sql監控、URI監控、Session監控,Web應用等等。


免責聲明!

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



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