DS注解作用

@DS(“#header.dbTenantId”) 是 MyBatis-Plus 框架中的注解,用于指定数据源。其中 #header.dbTenantId 表示从请求头中获取 dbTenantId 参数的值,作为数据源的标识。
@DS(“#tenantId”)中的 #tenantId 表示从方法参数中获取 tenantId 参数的值,作为数据源的标识。
@DS(“master”) 中的 “master” 表示数据源的标识,即指定使用名为 master 的数据源。
在多租户系统中,不同的租户可能需要连接不同的数据库,因此需要动态切换数据源。使用 @DS 注解可以方便地实现动态切换数据源的功能。通过在注解中指定数据源的标识,可以让 MyBatis-Plus 框架自动切换到对应的数据源,从而实现动态切换数据源的功能。
需要注意的是,使用 @DS 注解需要在 Spring Boot 配置文件中配置多个数据源,并在注解中指定数据源的标识。同时,也需要在代码中使用 @Mapper 注解标注 Mapper 接口,以便 MyBatis-Plus 框架能够自动扫描并生成对应的 Mapper 实现类。

样例:

spring:
  datasource:
    tenant1:
      url: jdbc:mysql://localhost:3306/tenant1_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver
    tenant2:
      url: jdbc:mysql://localhost:3306/tenant2_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

在上面的配置文件中,定义了两个数据源,分别为 tenant1 和 tenant2。其中,tenant1 数据源连接的是 tenant1_db 数据库,tenant2 数据源连接的是 tenant2_db 数据库。
在代码中,可以使用 @DS 注解动态指定使用哪个租户的数据源。例如:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @DS("#tenantId")
    @Override
    public List<User> listUsers(Long tenantId) {
        return userMapper.selectList(null);
    }
}

失效情况:
updateUser方法的数据源会覆盖掉getUserById方法的数据源
可以将getUserById方法放到另一个类中,使之代理注解生效

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    @Qualifier("dataSource1")
    private DataSource dataSource1;

    @Autowired
    @Qualifier("dataSource2")
    private DataSource dataSource2;

    @Override
    @DS("dataSource1")
    @Transactional(value = "transactionManager1")
    public User getUserById(int id) {
        // 使用dataSource1查询用户信息
        // ...
    }

    @Override
    @Transactional(value = "transactionManager2")
    @DS("dataSource2")
    public void updateUser(User user) {
        // 在这里调用getUserById方法,应该使用dataSource1数据源
        User oldUser = getUserById(user.getId());

        // 使用dataSource2更新用户信息
        // ...
    }
}

原因:

@DS注解是通过AOP实现的,它会在方法执行前切换数据源。而@Transactional注解也是通过AOP实现的,它会在方法执行前开启事务,并在方法执行后提交或回滚事务。
当一个方法同时被@DS和@Transactional注解修饰时,Spring会先创建一个代理对象,这个代理对象会同时包含@DS和@Transactional的功能。当代理对象调用这个方法时,它会先切换数据源,然后开启事务。在事务执行期间,如果这个方法调用了另一个方法,那么这个方法也会被代理对象所代理,也就是说,这个方法也会被切换到当前数据源,并且也会被包含在当前事务中。
如果在调用另一个方法时,这个方法上也有@DS注解,那么这个注解会被代理对象所覆盖,也就是说,这个方法会使用当前数据源,而不是它本来应该使用的数据源。这就是为什么@DS注解会被覆盖的原因。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhou22-codeWalker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值