方式一: 使用Spring提供的AbstractRoutingDataSource
配置文件
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource datasource1: url: jdbc:mysql://127.0.0.1:3306/dcytest?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource2: url: jdbc:mysql://127.0.0.1:3306/drools?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver
主要依赖
<!-- 阿里数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.1</version> </dependency>
核心代码
- 定义数据源注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface DS { // 默认数据源 String value() default "ds1"; }
- 使用AbstractRoutingDataSource返回当前数据源
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * @description: * @author: dcy * @create: 2024-01-20 20:27 */ public class DynamicDataSource extends AbstractRoutingDataSource { // 当前使用的数据源标识 public static ThreadLocal<String> name=new ThreadLocal<>(); // 返回当前数据源标识 @Override protected Object determineCurrentLookupKey() { return name.get(); } }
- 数据源配置
import cn.ac.zing.dyds.ds1.ds.DynamicDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; 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 javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * @description: * @author: dcy * @create: 2024-01-20 20:22 */ @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource.datasource1") public DataSource dataSource1() { // 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() { // 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean public DataSource myRoutingDataSource(@Qualifier("dataSource1") DataSource dataSource1, @Qualifier("dataSource2") DataSource dataSource2) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("ds1", dataSource1); targetDataSources.put("ds2", dataSource2); DynamicDataSource myRoutingDataSource = new DynamicDataSource(); myRoutingDataSource.setDefaultTargetDataSource(dataSource1); myRoutingDataSource.setTargetDataSources(targetDataSources); return myRoutingDataSource; } }
- MyBatis xml配置
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.annotation.Resource; import javax.sql.DataSource; /** * @description: * @author: dcy * @create: 2024-01-20 21:28 */ @EnableTransactionManagement @Configuration public class MyBatisConfig { @Resource(name = "myRoutingDataSource") private DataSource myRoutingDataSource; @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(myRoutingDataSource); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/**/*.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public PlatformTransactionManager platformTransactionManager() { return new DataSourceTransactionManager(myRoutingDataSource); } }
- 使用AOP设置需要使用的数据源
import cn.ac.zing.dyds.ds1.annotation.DS; import cn.ac.zing.dyds.ds1.ds.DynamicDataSource; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; /** * @description: * @author: dcy * @create: 2024-01-20 20:35 */ @Component @Aspect public class DynamicDataSourceAspect { // 前置 @Before("within(cn.ac.zing.dyds.ds1.service.impl.*) && @annotation(ds)") public void before(JoinPoint point, DS ds){ String name = ds.value(); DynamicDataSource.name.set(name); System.out.println(name); } }
使用
- mapper
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @Mapper public interface DSMapper { List<Map<String, Object>> selectStudentList(); List<Map<String, Object>> selectRuleInfoList(); }
- xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds1.mapper.DSMapper"> <select id="selectStudentList" resultType="java.util.Map"> select * from student </select> </mapper> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds1.mapper.DSMapper"> <select id="selectRuleInfoList" resultType="java.util.Map"> select * from rule_info </select> </mapper>
- service
import java.util.List; import java.util.Map; public interface DSService { List<Map<String, Object>> selectStudentList(); List<Map<String, Object>> selectRuleInfoList(); } import cn.ac.zing.dyds.ds1.annotation.DS; import cn.ac.zing.dyds.ds1.mapper.DSMapper; import cn.ac.zing.dyds.ds1.service.DSService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.Map; /** * @description: * @author: dcy * @create: 2024-01-20 20:33 */ @Service public class DSServiceImpl implements DSService { @Resource DSMapper dsMapper; @DS("ds1") @Override public List<Map<String, Object>> selectStudentList() { return dsMapper.selectStudentList(); } @DS("ds2") @Override public List<Map<String, Object>> selectRuleInfoList() { return dsMapper.selectRuleInfoList(); } }
方式二: 使用MyBatis注册多个SqlSessionFactory
配置文件
server: port: 8081 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource datasource1: url: jdbc:mysql://127.0.0.1:3306/dcytest?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource2: url: jdbc:mysql://127.0.0.1:3306/drools?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver
主要依赖
<!-- 阿里数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.1</version> </dependency>
数据源配置
- 数据源1
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; 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 org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; /** * @description: * @author: dcy * @create: 2024-01-20 21:52 */ @Configuration // 继承mybatis: // 1. 指定扫描的mapper接口包(主库) // 2. 指定使用sqlSessionFactory是哪个(主库) @MapperScan(basePackages = "cn.ac.zing.dyds.ds2.mapper.ds1", sqlSessionFactoryRef="ds1SqlSessionFactory") public class DS1Config { @Bean @ConfigurationProperties(prefix = "spring.datasource.datasource1") public DataSource dataSource1() { // 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @Primary public SqlSessionFactory ds1SqlSessionFactory() throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // 指定主库 sessionFactory.setDataSource(dataSource1()); // 指定主库对应的mapper.xml文件 sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/ds1/*.xml")); return sessionFactory.getObject(); } @Bean @Primary public DataSourceTransactionManager ds1TransactionManager(){ DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource1()); return dataSourceTransactionManager; } @Bean public TransactionTemplate ds1TransactionTemplate(){ return new TransactionTemplate(ds1TransactionManager()); } }
- 数据源2
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; 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 org.springframework.transaction.support.TransactionTemplate; import javax.sql.DataSource; /** * @description: * @author: dcy * @create: 2024-01-20 21:52 */ @Configuration // 继承mybatis: // 1. 指定扫描的mapper接口包(主库) // 2. 指定使用sqlSessionFactory是哪个(主库) @MapperScan(basePackages = "cn.ac.zing.dyds.ds2.mapper.ds2", sqlSessionFactoryRef="ds2SqlSessionFactory") public class DS2Config { @Bean @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() { // 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @Primary public SqlSessionFactory ds2SqlSessionFactory() throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // 指定主库 sessionFactory.setDataSource(dataSource2()); // 指定主库对应的mapper.xml文件 sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/ds2/*.xml")); return sessionFactory.getObject(); } @Bean @Primary public DataSourceTransactionManager ds2TransactionManager(){ DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource2()); return dataSourceTransactionManager; } @Bean public TransactionTemplate ds2TransactionTemplate(){ return new TransactionTemplate(ds2TransactionManager()); } }
使用
- DS1Mapper
import java.util.List; import java.util.Map; public interface DS1Mapper { List<Map<String, Object>> selectStudentList(); }
- DS2Mapper
import java.util.List; import java.util.Map; public interface DS2Mapper { List<Map<String, Object>> selectRuleInfoList(); }
- service
import java.util.List; import java.util.Map; public interface DSService { List<Map<String, Object>> selectStudentList(); List<Map<String, Object>> selectRuleInfoList(); } import cn.ac.zing.dyds.ds2.mapper.ds1.DS1Mapper; import cn.ac.zing.dyds.ds2.mapper.ds2.DS2Mapper; import cn.ac.zing.dyds.ds2.service.DSService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.Map; /** * @description: * @author: dcy * @create: 2024-01-20 20:33 */ @Service public class DSServiceImpl implements DSService { @Resource DS1Mapper ds1Mapper; @Resource DS2Mapper ds2Mapper; @Override public List<Map<String, Object>> selectStudentList() { return ds1Mapper.selectStudentList(); } @Override public List<Map<String, Object>> selectRuleInfoList() { return ds2Mapper.selectRuleInfoList(); } }
- xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds2.mapper.ds1.DS1Mapper"> <select id="selectStudentList" resultType="java.util.Map"> select * from student </select> </mapper> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds2.mapper.ds2.DS2Mapper"> <select id="selectRuleInfoList" resultType="java.util.Map"> select * from rule_info </select> </mapper>
方式三: 使用dynamic-datasource框架
配置文件
server: port: 8081 spring: datasource: dynamic: #设置默认的数据源或者数据源组,默认值即为datasource1 primary: ds1 #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 strict: false datasource: ds1: url: jdbc:mysql://127.0.0.1:3306/dcytest?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver ds2: url: jdbc:mysql://127.0.0.1:3306/drools?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver #配置mapper xml文件的路径 mybatis: mapper-locations: mapper/**/*.xml
核心依赖
<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.5.0</version> </dependency> </dependencies>
使用
- Mapper
import com.baomidou.dynamic.datasource.annotation.DS; import org.apache.ibatis.annotations.Mapper; import java.util.List; import java.util.Map; @Mapper public interface DSMapper { @DS("ds1") List<Map<String, Object>> selectStudentList(); @DS("ds2") List<Map<String, Object>> selectRuleInfoList(); }
- service
import java.util.List; import java.util.Map; public interface DSService { List<Map<String, Object>> selectStudentList(); List<Map<String, Object>> selectRuleInfoList(); } import cn.ac.zing.dyds.ds3.mapper.DSMapper; import cn.ac.zing.dyds.ds3.service.DSService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.Map; /** * @description: * @author: dcy * @create: 2024-01-20 20:33 */ @Service public class DSServiceImpl implements DSService { @Resource DSMapper dsMapper; @Override public List<Map<String, Object>> selectStudentList() { return dsMapper.selectStudentList(); } @Override public List<Map<String, Object>> selectRuleInfoList() { return dsMapper.selectRuleInfoList(); } }
- xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds3.mapper.DSMapper"> <select id="selectStudentList" resultType="java.util.Map"> select * from student </select> </mapper> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ac.zing.dyds.ds3.mapper.DSMapper"> <select id="selectRuleInfoList" resultType="java.util.Map"> select * from rule_info </select> </mapper>