一、前言
MybatisPlus多数据源配置主要解决的是多数据库连接和切换的问题。在一些大型应用中,由于数据量的增长或者业务模块的增多,可能需要访问多个数据库。这时,就需要配置多个数据源。
二、Springboot + MyBatis Plus 数据源配置
2.1、单数据源配置
2.1.1、引用依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency>
2.1.2、application.yml 配置
spring: datasource: url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
2.1.3、通用配置类
@Configuration @MapperScan(basePackages = {"com.xx.**.mapper"}) public class MybatisPlusConfig { public MybatisPlusInterceptor mybatisPlusInterceptor(){ //新的分页插件配置方法(Mybatis Plus 3.4.0版本及其之后的版本) MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mybatisPlusInterceptor; } }
2.1.4、使用方式
这里便不过多的说明具体的使用方式了,和正常的MyBatis plus 单库一样
2.2、多数据源配置
2.2.1、引用依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!-- 集成druid连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.9</version> </dependency> <!-- 多数据源所需要使用到的依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.1.0</version> </dependency>
2.2.2、在 application.yml
spring: # 配置数据源信息 datasource: dynamic: # 设置默认的数据源或者数据源组,默认值为master primary: master # 严格匹配数据源,默认false,true未匹配到指定数据源时抛异常,false使用默认数据源 strict: false datasource: master: url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 slave_1: url: jdbc:mysql://localhost:3306/demo?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=false driver-class-name: com.mysql.cj.jdbc.Driver username: root
2.2.3、通用配置类
@Configuration @MapperScan(basePackages = {"com.xx.**.mapper"}) public class MybatisPlusConfig { public MybatisPlusInterceptor mybatisPlusInterceptor(){ //新的分页插件配置方法(Mybatis Plus 3.4.0版本及其之后的版本) MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mybatisPlusInterceptor; } }
2.2.14.2、使用slave数据源
@Service @DS("slave") public interface TreeServiceImpl implements TreeService { @Autowired private TreeMapper treeMapper; /** * 使用 xml 自定义的查询方法 * * @return */ @DataSource(value = DataSourceType.SLAVE) public List<ZTree> selectThreeTreeNode(String faultDate) { return treeMapper.selectThreeTreeNode(); } /** * 使用 mybatis plus 的查询方法 * * @return */ @DataSource(value = DataSourceType.SLAVE) public List<ZTree> list(String faultDate) { return deptMapper.list(); } }
2.2.14.4、 Q&A
2.2.14.4.1 @Transactional 和 @DS 注解一起使用时, @DS失效的问题
这是因为 @Transactional 开启事务后, 就不会重新拿数据源,因为@DS也得通过切面去获取数据源, 这样就导致了@DS失效.
要解决的话, 就在要切换数据源的方法上也打上@DS, 或者多个数据源有修改操作可以都打上事务注解并改变传播机制,(但这其实是分布式事务的范畴, 这样操作不能保证事务了, plus也提供了
@DSTransactional 来支持, 不够需要借助seata)
2.2.14.4.2 针对@Transactional与@DSTransactional做一个简单的解释。
@Transactional是spring的注解目的就是开启事务,所以在该注解被扫描到的时候就去获取DataSource,此时DynamicDataSourceContextHolder队列中无任务元素,所以获取到的dsKey就是null,之后通过DynamicRoutingDataSource方法中的determinePrimaryDataSource获取主库的DataSource。
@DSTransactional是mp中的注解,该注解下的所有@DS注解在invoke方法中向DynamicDataSourceContextHolder中压入元素,之后在获取determineDataSource的时候或获取到一个dsKey从而选择正确的DataSource。