SpringBoot2集成Druid配置多數據數據源及SQL監控

記錄一下近期練習搭建項目Spingboot集成druid配置多數據源過程,本人也是小白,我會盡量描述的詳細,希望能幫助到你,也爲自己之後溫習做下準備。

1.開發環境

IntelliJ IDEA 2018.3.6 x64

jdk1.8

mysql 5.7

2.項目目錄結構

3.導入jar包

<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.59</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.19</version>
        </dependency>

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.0.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!-- 去掉scope作用域,使用默認的compile,編譯、測試、運行都有效的作用域 -->
            <!--<scope>slave</scope>-->
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.1</version>
        </dependency>

4.application.properties配置多個jdbc鏈接

我這裏沒有使用yml,其實都是差不多,yml複製粘貼名稱不太方便

##################    JDBC 配置    ################
#數據庫一配置
spring.datasource.druid.master.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.master.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.druid.master.username=root
spring.datasource.druid.master.password=123456

##########################  druid配置   ##########################
# 下面爲連接池的補充設置,應用到上面所有數據源中# 初始化大小,最小,最大
##################    連接池配置    ################
#連接池建立時創建的初始化連接數
spring.datasource.druid.master.initial-size=5
#連接池中最大的活躍連接數
spring.datasource.druid.master.max-active=20
#連接池中最小的活躍連接數
spring.datasource.druid.master.min-idle=5
# 配置獲取連接等待超時的時間
spring.datasource.druid.master.max-wait=60000
# 打開PSCache,並且指定每個連接上PSCache的大小
spring.datasource.druid.master.pool-prepared-statements=true
spring.datasource.druid.master.max-pool-prepared-statement-per-connection-size=20
#spring.datasource.druid.max-open-prepared-statements= #和上面的等價
spring.datasource.druid.master.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.master.validation-query-timeout=30000
#是否在獲得連接後檢測其可用性
spring.datasource.druid.master.test-on-borrow=false
#是否在連接放回連接池後檢測其可用性
spring.datasource.druid.master.test-on-return=false
#是否在連接空閒一段時間後檢測其可用性
spring.datasource.druid.master.test-while-idle=true
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆,log4j2爲你自己使用的日誌,如果是log4j就寫log4j,我這裏用的log4j2
spring.datasource.druid.master.filters=stat,wall,log4j2
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.druid.master.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合併多個DruidDataSource的監控數據
#spring.datasource.druid.master.useGlobalDataSourceStat=true


#數據庫二配置
spring.datasource.druid.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.slave.url=jdbc:mysql://10.0.0.1:3306/mysql3235?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC   //根據自己需要修改第二個jdbc鏈接
spring.datasource.druid.slave.username=root
spring.datasource.druid.slave.password=121111
##########################  druid配置   ##########################
# 下面爲連接池的補充設置,應用到上面所有數據源中# 初始化大小,最小,最大
##################    連接池配置    ################
#連接池建立時創建的初始化連接數
spring.datasource.druid.slave.initial-size=5
#連接池中最大的活躍連接數
spring.datasource.druid.slave.max-active=20
#連接池中最小的活躍連接數
spring.datasource.druid.slave.min-idle=5
# 配置獲取連接等待超時的時間
spring.datasource.druid.slave.max-wait=60000
# 打開PSCache,並且指定每個連接上PSCache的大小
spring.datasource.druid.slave.pool-prepared-statements=true
spring.datasource.druid.slave.max-pool-prepared-statement-per-connection-size=20
#spring.datasource.druid.max-open-prepared-statements= #和上面的等價
spring.datasource.druid.slave.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.slave.validation-query-timeout=30000
#是否在獲得連接後檢測其可用性
spring.datasource.druid.slave.test-on-borrow=false
#是否在連接放回連接池後檢測其可用性
spring.datasource.druid.slave.test-on-return=false
#是否在連接空閒一段時間後檢測其可用性
spring.datasource.druid.slave.test-while-idle=true
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
spring.datasource.druid.slave.filters=stat,wall,log4j2
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.druid.slave.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合併多個DruidDataSource的監控數據
#spring.datasource.druid.slave.useGlobalDataSourceStat=true

5.druid 配置(基於java版)

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
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 java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {
    /**
     * 配置Druid監控
     * 後臺管理Servlet
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();//這是配置的druid監控的登錄密碼
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","admin");
        //默認就是允許所有訪問
        initParams.put("allow","");
        //黑名單的IP
        initParams.put("deny","192.168.15.21");
        bean.setInitParameters(initParams);
        return bean;
    }
    /**
     * 配置web監控的filter
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
         initParams.put("exclusions","/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");//過濾掉需要監控的文件
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return  bean;
    }
}

6.綁定數據源(有幾個數據源就需要寫幾個java文件)

mport com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.yadu.example.demo.mapper.master", sqlSessionTemplateRef  = "masterSqlSessionTemplate")
public class MasterDataSourceConfiguration {

    @Bean(name = "masterDataSource")
    @Primary   //配置默認數據源
    @ConfigurationProperties(prefix = "spring.datasource.druid.master")
    public DataSource dataSource() {
        return  new DruidDataSource();
    }

    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "masterSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory)
            throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    

}
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;


@Configuration
@MapperScan(basePackages = "com.yadu.example.demo.mapper.slave", sqlSessionTemplateRef  = "slaveSqlSessionTemplate")
public class SlaverDataSourceConfiguration {

    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.slave")
    public DataSource dataSource() {
        return  new DruidDataSource();
    }

    @Bean(name = "slaveSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "slaveTransactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "slaveSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory)
            throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

7.配置spring監控(如果你訪問方法之後spring監控沒有數據)

import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * spring監控配置
 * @author
 */
@Configuration
public class SpringDaoMethodAspect {
	
	@Bean
	public DruidStatInterceptor druidStatInterceptor() {
		DruidStatInterceptor dsInterceptor = new DruidStatInterceptor();
		return dsInterceptor;
	}
	
	@Bean
	@Scope("prototype")
	public JdkRegexpMethodPointcut druidStatPointcut() {
		JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
		pointcut.setPattern("com.yadu.example.demo.mapper.*");
		return pointcut;
	}
	
	@Bean
	public DefaultPointcutAdvisor druidStatAdvisor(DruidStatInterceptor druidStatInterceptor, JdkRegexpMethodPointcut druidStatPointcut) {
		DefaultPointcutAdvisor defaultPointAdvisor = new DefaultPointcutAdvisor();
		defaultPointAdvisor.setPointcut(druidStatPointcut);
		defaultPointAdvisor.setAdvice(druidStatInterceptor);
		return defaultPointAdvisor;
	}
}

8.springboot啓動類

注意看下註解,這點容易出錯,一開始我加了@MapperScan和@ComponentScan,導致tomcat啓動中斷,也不報錯,然後我還在main方法裏面加了try catch,錯誤信息纔出來,是這兩個註解引起了,導致我一個包掃描了兩次,我網上查了資料,可以同時使用,咱也不知道爲啥出錯。。。

9.編寫方法,驗證效果

http://localhost:8079/test   端口號我這裏在application.properties 中修改了,改成你對應的端口號就好

sql監控訪問

http://localhost:8079/druid/index.html

 

10.作爲補充

訪問sql監控的時候,你可能會看到阿里巴巴的廣告,如果想去掉,有兩種方式

1.修改druid中的js源碼,可參考

https://blog.csdn.net/haveqing/article/details/86524672

2.增加配置文件

https://blog.csdn.net/qq_33229669/article/details/87459781

親測兩種方式都可以,我使用的是第一種,從根源解決

如果你第一次使用,可能會遇到各種各樣問題,可以留言一起研究

使用心得,其實搭建完我才知道,springboot2有自己默認的連接池HikariCP,具體鏈接可參考https://www.jianshu.com/p/7e4c0e9ad49a,哪個比較好,請根據自己項目選擇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章