記錄一下近期練習搭建項目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,哪個比較好,請根據自己項目選擇