利用AOP和AbstractRoutingDataSource实现动态切换数据源

背景
公司有多套环境,每个环境执行数据库脚本的时机也不一样,久而久之,不同环境相同表的结构就有了差异,需要做一个工具进行对比。

分析
同一套环境下有很多数据库,不同环境的数据库连接肯定也是不一样的,那么如何做到查询指定环境下的某一个数据库,需要动态的去切换数据源,根据当前的查询条件路由对应的数据库。可以使用AOP在执行SQL前切换数据源。

实现逻辑

  1. 用 AbstractRoutingDataSource 实现动态切换数据源,向容器中注册自定义的 AbstractRoutingDataSource 实现类(AbstractRoutingDataSource的相关介绍,我这篇文章有介绍,点我)。
  2. 用 ThreadLocal 线程级别变量存放当前数据源key。
  3. 利用 AOP 在执行SQL时切换数据源。

我这里因为公司使用的是阿里的DRDS,数据库是按照用户名进行隔离的,一个用户名对应一个数据库,所以多套环境下数据库的url连接都是一样的,只是连接的账号密码不一样,所以只需要把账号和密码配置在 application.xml 中。

spring:
  datasource:
    default:
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://xxxxxxx/xxx?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
      username: xxx
      password: xxx
    databaselist:
      - database: dev_xx1
        username: dev_xx1
        password: dev_123
      - database: dev_xx2
        username: dev_xx2
        password: dev_123
      - database: test_xx1
        username: test_xx1
        password: test_123
      - database: test_xx2
        username: test_xx2
        password: test_123

mybatis:
  mapper-locations: classpath:/mapper/*.xml

DataSourceContextHolder


/**
 * 数据源上下文
 */
@Slf4j
@UtilityClass
public class DataSourceContextHolder {
   

    /**
     * 线程级别的私有变量
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    public String getDataSourceName() {
   
        return CONTEXT_HOLDER.get();
    }

    public void setDataSourceName(String name) {
   
        log.info("切换到:{}数据源", name);
        CONTEXT_HOLDER
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值