springboot配置多个数据源
1、bean的配置
1.1、yml文件配置文件:
spring:
datasource:
first:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/mybatisplus?useSSL=false&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
second:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
# 注:这里的url要改成jdbc-url
新建配置包:dataconf,新建两个配置类:
1.2、DataSourceOne 配置类:
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Configuration
@MapperScan(basePackages = {"com.bayis.mybatisplus.mapper.db1"},sqlSessionFactoryRef = "db1SqlSessionFactory")
public class DataSourceOne {
@Primary // 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
@Bean("db1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.first") //读取application.yml中的配置参数映射成为一个对象
public DataSource getDb1DataSource(){
return DataSourceBuilder.create().build();
}
@Primary
@Bean("db1SqlSessionFactory")
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.bayis.mybatisplus.entity");
/*
此处calsspath只能写一个,写多个无效,而且配置了哪个数据源包,只能在那个数据源包下写当前配置数据源的mapper接口包下,mapper包下不能写多
数据库的表操作,一个mapper包只能写一个数据库的表操作
*/
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*Mapper.xml"));
return bean.getObject();
}
//配置事务管理器,对事物进行管理
@Primary
@Bean("db1DataSourceTransactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("db1DataSource")DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Primary
@Bean("db1SqlSessionTemplate")
public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
//此处尝试写多个mapper路径,结果测试不行(建议这里不用写)
public Resource[] resolveMapperLocations() {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<String> mapperLocations = new ArrayList<>();
mapperLocations.add("classpath:mapper/db1/*Mapper.xml");
mapperLocations.add("classpath:mapper/db2/*Mapper.xml");
List<Resource> resources = new ArrayList();
if (!CollectionUtils.isEmpty(mapperLocations)) {
for (String mapperLocation : mapperLocations) {
try {
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return resources.toArray(new Resource[resources.size()]);
}
}
1.3、DataSourceTwo 配置类:
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Configuration
@MapperScan(basePackages = {"com.bayis.mybatisplus.mapper.db2"},sqlSessionFactoryRef = "db2SqlSessionFactory")
public class DataSourceTwo {
@Bean("db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource getdb2DataSource(){
return DataSourceBuilder.create().build();
}
@Bean("db2SqlSessionFactory")
public SqlSessionFactory db2SqlSessionFactory(@Qualifier("db2DataSource")DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.bayis.mybatisplus.entity");
/*
此处calsspath只能写一个,写多个无效,而且配置了哪个数据源包,只能在那个数据源包下写当前配置数据源的mapper接口包下,mapper包下不能写多
数据库的表操作,一个mapper包只能写一个数据库的表操作
*/
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/*Mapper.xml"));
return bean.getObject();
}
@Bean("db2DataSourceTransactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("db2DataSource")DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean("db2SqlSessionTemplate")
public SqlSessionTemplate db2SqlSessionTemplate(@Qualifier("db2SqlSessionFactory")SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
//此处尝试写多个mapper路径,结果测试不行(建议这里不用写)
public Resource[] resolveMapperLocations() {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<String> mapperLocations = new ArrayList<>();
mapperLocations.add("classpath:mapper/db1/*Mapper.xml");
mapperLocations.add("classpath:mapper/db2/*Mapper.xml");
List<Resource> resources = new ArrayList();
if (!CollectionUtils.isEmpty(mapperLocations)) {
for (String mapperLocation : mapperLocations) {
try {
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
} catch (IOException e) {
e.printStackTrace();
}
}
}
return resources.toArray(new Resource[resources.size()]);
}
}
2、MyBatisPlus配置:
2.1、引入dynamic-datasource-spring-boot-starter。
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>
2.2、配置数据源。
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/mybatisplus?useSSL=false&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
dev:
url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 如果想要在添加数据源,以次类推即可
# 多主多从 纯粹多库(记得设置primary) 混合配置
spring: spring: spring:
datasource: datasource: datasource:
dynamic: dynamic: dynamic:
datasource: datasource: datasource:
master_1: mysql: master:
master_2: oracle: slave_1:
slave_1: sqlserver: slave_2:
slave_2: postgresql: oracle_1:
slave_3: h2: oracle_2:
2.3、使用 @DS 切换数据源。
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
注解 | 结果 |
---|---|
没有@DS | 默认数据源 |
@DS(“dsName”) | dsName可以为组名也可以为具体某个库的名称 |
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}