Mybatis-plus 多数据动态数据源配置

liuqiang 2021年05月19日 17次浏览

方案1

Mybatis-plus 多数据源
reference

<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

application.yml

pring:
  datasource:
    #reference: https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
    dynamic:
      mp-enabled: true
      hikari:
        maximum-pool-size: 4
        minimum-idle: 2
        pool-name: 'hikariPool'
        connection-timeout: 6000
        idle-timeout: 60000
        connection-test-query: select 1
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://10.50.306/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
          username: ENC(F6faQmA==)
          password: ENC(m1rPAzTjzmOG+elz2CQ3Nt7iRg+iYFuU)
          driver-class-name: com.mysql.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource
        other-ds:
          url: jdbc:mysql://localhost:3306/db_xxpt?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password:
          driver-class-name: com.mysql.jdbc.Driver
          type: com.zaxxer.hikari.HikariDataSource

# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

使用示例

public interface DSNameConstant {

    /**
     * 默认数据源 wms系统使用
     */
    String WMS_SERVER_DEFAULT = "master";

    String OTHER ="other-ds";
}
@Service
@Slf4j
public class DSDemoServiceImpl implements DSDemoService {

    @Autowired
    private TrustBaseInfoService trustBaseInfoService;

    @Autowired
    private OtherMapper oTherMapper;


    @Autowired
    private DynamicTestService dynamicTestService;

    @Override
    public void selectTest() {
        try {
            //默认数据源
            selectWms();
            // 其他数据源
            /**
             * mybatis-plus数据源是利用spring-aop实现的,对于aop而言它是以每次请求为单位的,
             * 简单的说,虽然我们使用了两个方法,分别配置了两个@DS("),但其实第二个并不会生效
             * 解决办法,对于一次请求两个数据源在把第二个数据源改为手动修改,下面的手动修改配置
             * reference:https://www.cnblogs.com/drott/p/14596514.html
             */
            DynamicDataSourceContextHolder.push(DSNameConstant.OTHER);
            selectOther();
            DynamicDataSourceContextHolder.poll();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 嵌套数据源的service中,如果操作了多个数据源,不能在最外层加上@Transaction开启事务,否则切换数据源不生效,因为这属于分布式事务了,
     * 需要用seata方案解决,如果是单个数据源(不需要切换数据源)可以用@Transaction开启事务,保证每个数据源自己的完整性
     */
    @Transactional
    @Override
    public void saveTest()  {
        //trustBaseInfoService.saveTrustBaseInfo()
        DynamicTest dynamicTest = new DynamicTest();
        dynamicTest.setName(UUID.randomUUID().toString());
        dynamicTestService.save(dynamicTest);
        log.info("开始saveTest insert ...");
        //throw new BusinessException("测试单数据源异常事务回滚");
    }

    /**
     * wms 数据源
     * @throws Exception
     */
    @DS(DSNameConstant.WMS_SERVER_DEFAULT)
    public void selectWms() throws Exception {
        TrustBaseInfo result = trustBaseInfoService.getTrustBaseInfoById("109");
        log.info("result #### {}",result);
    }



    /**
     * 其他数据源
     */
    @DS(DSNameConstant.OTHER)
    @Override
    public void selectOther() {
        List<Map> maps = oTherMapper.selectList();
        log.info("result #### {}",maps);
    }