zoukankan      html  css  js  c++  java
  • mybatis动态切换数据源

    (#)背景:由于业务的需求,导致需要随时切换15个数据源,此时不能low逼的去写十几个mapper,所以想到了实现一个数据源的动态切换

    首先要想重写多数据源,那么你应该理解数据源的一个概念是什么,DataSourceTransactionManager这个类就是spring中对于数据源的封装,其中DataSource做为

    他的一个成员.接下来我们要介绍一下我们切换动态数据源需要使用的类,AbstractRoutingDataSource,先来看看这个类的源码

    首先看看这几个变量,targetDataSources代表的就是备选的数据源了,用一个map存储,显然是为了在关键的时候快速的查找这些数据源,defaultTargetDataSource

    就是我们在配置的时候一般都会制定一个默认的数据源就是它了,

    程序运行的时候在加载配置文件的时候,首先会执行setTargetDataSources方法,这个方法会加载配置文件中配置的数据源,存储在上面说的targetDataSource中,

    然后是设置setDefaultTergetDataSource,这个就是上面说的默认的数据源,

    接下来会执行这个方法,在其中会将所有的数据源用来初始化resolvedDataSources,而当实际上和数据库产生交互的时候那么会调用到下面的方法:

    如果看到这里大概你也知道怎么回事了,在我们实际和数据库产生交互的时候那么就需要使用到数据源了,那么这个时候我们只是需要重写这determineCurrentLookupKey

    方法,而用这个方法具体干了什么呢?就是用它来寻找数据源啊,也就是说我们在mapper中的配置:

    (#)下面看看代码上怎么来写

    首先为了线程安全我们使用一个ThreadLocal来做存储

    public class ContextHolder {
        public static final String DATASOURCE_1="dataSource";
        public static final String DATASOURCE_2="dataSource2";
    
        private static final ThreadLocal<String> context = new ThreadLocal<String>();
    
        public static void setConsumerType(String consumerType){
            context.set(consumerType);
        }
    
        public static String getConsumerType(){
            return context.get();
        }
    
        public static void clearConsumerType(){
            context.remove();
        }
    }
    

      

    public class DynamicDataSource extends AbstractRoutingDataSource {
        @Override
        protected Object determineCurrentLookupKey() {
            return ContextHolder.getConsumerType();
        }
    }
    

      其实剩下的怎么实现已经很简单了,基本思路就是使用一个动态代理,在执行这个方法的时候,我们动态的给ContextHoler设置值,我建议使用spring aop,或者如果

    不是spring的项目,那么直接只用动态代理也是很好的我觉,下面贴出一些我的简陋的代码

    @Aspect
    @Component
    public class DataSourceAspect {
    
        @Pointcut("execution(* com.wang.route.DynamicPersonService.*(..))")
        public void pointCut() {
        }
    
    
        @Before(value = "pointCut()")
        public void before(JoinPoint joinPoint) {
         
                ContextHolder.setConsumerTyp(“”);
            
        }
    }
    

      

  • 相关阅读:
    论文阅读:Single Image Dehazing via Conditional Generative Adversarial Network
    lintcode-720重排带整数字符串
    lintcode-828. 字模式
    lintcode-1038. 珠宝和石头
    lintcode-1174.下一个更大的元素 III
    lintcode-80.中位数
    《大道至简》第二章读后感
    从命令行输出数字,求和计算
    《大道至简》第一章伪代码观后感
    ngx_http_referer_module模块说明
  • 原文地址:https://www.cnblogs.com/wscit/p/6257539.html
Copyright © 2011-2022 走看看