多数据源的搭建方式有很多种
我这里就用自定义数据源来完成
开发环境:IDEA(2017),JDK(1.8),Maven(3.3.9),SpringBoot 2.0以上
pom配置
<!--数据库连接驱动和连接池依赖-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.1.4</version>
</dependency>
第二步:application.properties文件
#master数据库
app.datasource.master.type = com.alibaba.druid.pool.DruidDataSource
app.datasource.master.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
app.datasource.master.username=root
app.datasource.master.password=mysql
app.datasource.master.driverClassName=com.mysql.cj.jdbc.Driver
#master数据库druid配置
app.datasource.master.initialSize=5
app.datasource.master.minIdle=5
app.datasource.master.maxActive=20
app.datasource.master.maxWait=60000
app.datasource.master.timeBetweenEvictionRunsMillis=60000
app.datasource.master.minEvictableIdleTimeMillis=300000
app.datasource.master.validationQuery=SELECT 1 FROM DUAL
app.datasource.master.testWhileIdle=true
app.datasource.master.testOnBorrow=false
app.datasource.master.testOnReturn=false
app.datasource.master.poolPreparedStatements=true
app.datasource.master.maxPoolPreparedStatementPerConnectionSize=20
app.datasource.master.filters=stat,wall,cat
#slaver数据库
app.datasource.slaver.type = com.alibaba.druid.pool.DruidDataSource
app.datasource.slaver.url=jdbc:mysql://localhost:3306/springboot?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
app.datasource.slaver.username=root
app.datasource.slaver.password=mysql
app.datasource.slaver.driverClassName=com.mysql.cj.jdbc.Driver
#slaver数据库druid配置
app.datasource.slaver.initialSize=5
app.datasource.slaver.minIdle=5
app.datasource.slaver.maxActive=20
app.datasource.slaver.maxWait=60000
app.datasource.slaver.timeBetweenEvictionRunsMillis=60000
app.datasource.slaver.minEvictableIdleTimeMillis=300000
app.datasource.slaver.validationQuery=SELECT 1 FROM DUAL
app.datasource.slaver.testWhileIdle=true
app.datasource.slaver.testOnBorrow=false
app.datasource.slaver.testOnReturn=false
app.datasource.slaver.poolPreparedStatements=true
app.datasource.slaver.maxPoolPreparedStatementPerConnectionSize=20
app.datasource.slaver.filters=stat,wall,cat
第三步:自定义数据源
第一个数据源
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceMBean;
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.example.dao.dal.master", sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class MasterDataSourceConfiguration {
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "app.datasource.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:mapper/master/*.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.example.dao.dal.slave", sqlSessionTemplateRef = "slaveSqlSessionTemplate")
public class SlaverDataSourceConfiguration {
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "app.datasource.slaver")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/slaver/*.xml"));
return bean.getObject();
}
@Bean(name = "slaveTransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "slaveSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory)
throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
解答一下基本的问题
1.为什么不用 @Primary?
因为既没有注入顺序问题,也没有名称问题(已经起名字了),也没有使用@Autowired
2.为什么不用exclude = {DataSourceAutoConfiguration.class}?
如果你的自定义数据源用了spirng.datasource.的近似名称(或者环境变量中有该配置如:spirng.datasource.url),在有些版本会导致启动自定义配置,即使是最新的版本在自定义数据源的时候,也不推荐有这样起名字
具体可以看DataSourceAutoConfiguration的不自定的规则
我简单截取注解,你们就应该明白了
public class DataSourceAutoConfiguration {
@Configuration
@Conditional(EmbeddedDatabaseCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import(EmbeddedDataSourceConfiguration.class)
protected static class EmbeddedDatabaseConfiguration {
}
3.application.properties 有些参数命名的坑.怎么办?
这里去理解ConfigurationProperties这个注解是干啥,再去关注你要注入的对应类,你就明白了.
参考文章:
https://blog.csdn.net/qq_38455201/article/details/80769354
https://blog.csdn.net/Mars_wen/article/details/81116430
springboot指南-强推荐
https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#boot-features-logging-format