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(“”);
        
    }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM