Menu Close

Mybatis-plus配置多数据源,连接多数据库

1. 业务需求

1.1. 场景说明

多数据源适用于多种场景:纯粹多库、读写分离、一主多从、混合模式等等。

在这里我们模拟一个纯粹多库的场景,其他场景类似。我们创建两个库(一个为Oracle数据库,一个为MariaDB数据库),Oracle中有一张表 mpa_test, 而 MariaDB 中有一张表 mpb_test 通过一个测试用例分别获取表中数据,如果获取到说明多库模拟成功。

1.2. 业务逻辑

1.3. 数据库模拟数据

-- Oracle
CREATE TABLE mpa_account (acc_num INT NOT NULL,
                         acc_name VARCHAR2(20),
                         phone_no INT NOT NULL,
                         update_time DATE DEFAULT SYSDATE NOT NULL ,
                         CONSTRAINT pk_mpa_account PRIMARY KEY(acc_num));

INSERT INTO mpa_account (acc_num,acc_name,phone_no) VALUES(11,'Liucc11',13100000011);
INSERT INTO mpa_account (acc_num,acc_name,phone_no) VALUES(12,'Liucc12',13100000012);
INSERT INTO mpa_account (acc_num,acc_name,phone_no) VALUES(13,'Liucc13',13100000013);
COMMIT;

-- MariaDB
DROP TABLE IF EXISTS mpb_account;

CREATE TABLE mpb_account (acc_num INT NOT NULL,
                          acc_name VARCHAR(20),
                          phone_no NUMERIC(11) NOT NULL,
                          update_time DATETIME DEFAULT CURRENT_TIMESTAMP() NOT NULL ,
                          PRIMARY KEY(acc_num));

INSERT INTO mpb_account (acc_num,acc_name,phone_no) VALUES(21,'Liucc21',18900000021);
INSERT INTO mpb_account (acc_num,acc_name,phone_no) VALUES(22,'Liucc22',18900000022);
INSERT INTO mpb_account (acc_num,acc_name,phone_no) VALUES(23,'Liucc23',18900000023);
COMMIT;

2. 代码实现

2.1. 创建目录

2.2. 引入依赖

  • MyBatis Plus(包含了 mybatis-plus-extension)
    mybatis-plus-boot-starter

  • 动态数据源:Dynamic Datasource Spring Boot Starter
    dynamic-datasource-spring-boot-starter

  • lombok:Project Lombok
    lombok

  • oracle连接驱动: Ojdbc8
    Ojdbc8

  • MariaDB连接驱动:MariaDB Java Client
    mariadb-java-client

  • Orai18n:Orai18n
    Orai18n

2.3. 配置日志输出方式

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.log4j2.Log4j2Impl

2.4. 配置数据源

创建 application.yml 文件,编写数据库访问方式信息:

spring:
  datasource:
    dynamic:
      primary: oracle
      strict: false
      datasource:
        oracle:
          driver-class-name: oracle.jdbc.driver.OracleDriver
          url: jdbc:oracle:thin:@192.168.5.103/etdb2
          username: study
          password: study
        mariadb:
          drive-class-name: org.mariadb.jdbc.Driver
          url: jdbc:mariadb://192.168.4.43:6006/study
          username: study
          password: study

2.5. 生成代码

利用插件 MaBatisX 生成代码,参见: http://dba.qishuo.xin/?p=1395

2.6. 添加@DS注解

@DS注解先必须要写在mapper上,不然数据源无法切换。报如下错误:

其次@DS 可以注解在方法上和类上。如果同时存在,方法注解优先于类上注解。强烈建议注解在 service 实现或 mapper 接口方法上。

例如:

  • Mapper
@Repository
@DS("oracle")
public interface MpaAccountMapper extends BaseMapper<MpaAccount> {

}

@Repository
@DS("mariadb")
public interface MpbAccountMapper extends BaseMapper<MpbAccount> {

}
  • service
// Service
public interface MpaAccountService extends IService<MpaAccount> {

}

public interface MpbAccountService extends IService<MpbAccount> {

}

// Service Implement
@Service
@DS("oracle")
public class MpaAccountServiceImpl extends ServiceImpl<MpaAccountMapper, MpaAccount>
    implements MpaAccountService{

}

@Service
@DS("mariadb")
public class MpbAccountServiceImpl extends ServiceImpl<MpbAccountMapper, MpbAccount>
    implements MpbAccountService{

}

2.7. 在SprintBoot主启动器中添加 MapperScan

@MapperScan("com.hz571.easytong_etl.mapper")

2.8. 测试类

    @Test
    public void testMoreDS(){
        System.out.println(mpaAccountMapper.selectById(11));
        System.out.println(mpbAccountMapper.selectById(21));
    }

3. 注意事项

  1. 不能使用事务,否则数据源不会切换,使用的还是是第一次加载的数据源 (待确认)
  2. 删除 操作多数据源的方法或者类、接口 上的 注解 @Transactional(rollbackFor = Exception.class) 即可。
  3. 第一次加载的数据源之后,第二次(第三次...)操作其它数据源,如果数据源不存在,使用的还是第一次加载的数据源
  4. 数据源名称最好不要包含下滑线,下滑线的数据源切换不了

附录A

A.1. 参考: