mybatis-plus 多数据源配置

1. 双数据库创建

             mybatis-plus 多数据源配置_第1张图片

       两个数据库各有一张表

2. yml中配置双数据库

      下面的配置来源于mybatis-plus官网

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://1.XX.xx.58:3306/mybatis_plus?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave:
          url: jdbc:mysql://1.XX.xx.58:3306/hostDataBase?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.cj.jdbc.Driver

3. Mapper和Service

   3.1 两个表对应的结构体

        表 SPF_Require_Vehicle 对应的结构体

@TableName("SPF_Require_Vehicle")
@Data
public class Employee {
    /**
     * 指定主键名称为SPF_uid, 类型为自增,即数据库的字段必须是auto_increment
     */
    @TableId(value = "SPF_UID", type = IdType.AUTO)
    private Long id;

    /**
     * 指定数据库中对应的字段是 Part_PartSap
     */
    @TableField("Part_PartSap")
    private String partSap;

    @TableField("Part_PlateSap")
    private String plateSap;

    @TableField("SPF_Name")
    private String name;

    /**
     * 逻辑删除
     */
    @TableLogic(value = "0", delval = "1")
    @TableField("IsActvie")
    private Boolean active;

    @TableField("gender")
    private SexEnum gender;
}

         表Employer对应的结构体

  

@Data
@TableName("Employer")
public class EmployeerDO {
    @TableId(value = "SPF_Id", type = IdType.AUTO)
    private Long id;

    @TableField("SPF_Name")
    private String name;

    @TableField("SPF_Age")
    private int age;

    @TableLogic(value = "0", delval = "1")
    @TableField("IsActive")
    private Boolean active;
}

 3.2 两个Mapper

public interface EmployeeMapper extends BaseMapper {
    /**
     * 手写语句实现分页查询
     * @param page 拦截器使用,当前sql中不需要
     * @param employee 查询对象
     * @return 查询结果
     */
    Page getEmployeeInfoByPage(@Param("page") Page page, @Param("employee") Employee employee);

}
public interface EmployerMapper extends BaseMapper {
}

3.3 两个service

@Service
/**
 * 指明当前service处理的是master数据库
 */
@DS("master")
@Transactional(rollbackFor = Exception.class)
public class EmployeeServiceImpl extends ServiceImpl implements EmployeeService {
    @Override
    public List getEmployeeInfoByPage(Employee employee) {
        Page page = new Page<>(1, 3);
        Employee e1 = new Employee();
        e1.setName("wangshun");
        this.baseMapper.getEmployeeInfoByPage(page, e1);
        return page.getRecords();
    }
}
@Service
/**
 * 当前service使用的是slave数据库
 */
@DS("slave")
@Transactional(rollbackFor = Exception.class)
public class EmployerServiceImpl extends ServiceImpl implements EmployerService {
}

3.4  调用侧

        

@Autowired
    private EmployeeService employeeService;

    @GetMapping("/saveInfo")
    @ApiOperation(value = "Employer测试")
    /**
     * 如果涉及到多个数据源,则需要使用该注解
     */
    @DSTransactional
    public void saveEmployerInfo() {
        EmployeerDO employeerDO = new EmployeerDO();
        employeerDO.setAge(25);
        employeerDO.setName("zhangsan");

        Employee employee = new Employee();
        employee.setGender(SexEnum.SEX_FEMALE);
        // 该项为必填项,此处插入抛出异常,整个事务回滚
        //employee.setPartSap("xxxxx-yy");
        employee.setPlateSap("yyyyy-xx");
        employee.setName("111111111");
        this.employerService.save(employeerDO);
        this.employeeService.save(employee);
    }

    @GetMapping("/saveEmployee")
    @ApiOperation(value = "Employee测试")
    /**
     * 单个service,使用传统事务即可
     */
    @Transactional(rollbackFor = Exception.class)
    public void testEmployee() {
        Employee employee = new Employee();
        employee.setGender(SexEnum.SEX_FEMALE);
        employee.setPartSap("xxxxx-yy");
        employee.setPlateSap("yyyyy-xx");
        employee.setName("111111111");
        this.employeeService.save(employee);
        // 事务会回滚
        int tmp = 1/0;
        this.employeeService.getEmployeeInfoByPage(null);
    }

4.  @DSTransactional

        该注解和@Transaction的区别在于: 当一个函数中同时操作多个数据源时,即有多个service,则需要使用@DSTransactional 注解; 如果一个函数中操作的是同一个数据源,即只有一个service,则只需要使用 @Transactional

见    @Transactional和@DS避免数据源冲突的解决方案(提供gitee源码)_@dstransactional_一个资深码农的博客-CSDN博客

你可能感兴趣的:(数据库)