javascript
Spring MVC+Mybatis 多数据源配置
文章來(lái)自:https://www.jianshu.com/p/fddcc1a6b2d8
1. 繼承AbstractRoutingDataSource
AbstractRoutingDataSource 是spring提供的一個(gè)多數(shù)據(jù)源抽象類(lèi)。spring會(huì)在使用事務(wù)的地方來(lái)調(diào)用此類(lèi)的determineCurrentLookupKey()方法來(lái)獲取數(shù)據(jù)源的key值。我們繼承此抽象類(lèi)并實(shí)現(xiàn)此方法:
package com.ctitc.collect.manage.datasource;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /*** * @author zongbo * 實(shí)現(xiàn)spring多路由配置,由spring調(diào)用 */ public class DataSourceRouter extends AbstractRoutingDataSource { // 獲取數(shù)據(jù)源名稱(chēng) protected Object determineCurrentLookupKey() { return HandleDataSource.getDataSource(); } }2. 線(xiàn)程內(nèi)部數(shù)據(jù)源處理類(lèi)
DataSourceRouter 類(lèi)中通過(guò)HandleDataSource.getDataSource()獲取數(shù)據(jù)源的key值。此方法應(yīng)該和線(xiàn)程綁定。
package com.ctitc.collect.manage.datasource; /*** 線(xiàn)程相關(guān)的數(shù)據(jù)源處理類(lèi)* @author zongbo**/ public class HandleDataSource { // 數(shù)據(jù)源名稱(chēng)線(xiàn)程池 private static final ThreadLocal<String> holder = new ThreadLocal<String>(); /** * 設(shè)置數(shù)據(jù)源 * @param datasource 數(shù)據(jù)源名稱(chēng) */ public static void setDataSource(String datasource) { holder.set(datasource); } /** * 獲取數(shù)據(jù)源 * @return 數(shù)據(jù)源名稱(chēng) */ public static String getDataSource() { return holder.get(); } /** * 清空數(shù)據(jù)源 */ public static void clearDataSource() { holder.remove(); } }3. 自定義數(shù)據(jù)源注解類(lèi)
對(duì)于spring來(lái)說(shuō),注解即簡(jiǎn)單方便且可讀性也高。所以,我們也通過(guò)注解在service的方法前指定所用的數(shù)據(jù)源。我們先定義自己的注解類(lèi),其中value為數(shù)據(jù)源的key值。
package com.ctitc.collect.manage.datasource; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 數(shù)據(jù)源注解類(lèi) * @author zongbo * */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface DataSource { String value(); }4. AOP 攔截service并切換數(shù)據(jù)源
指定注解以后,我們可以通過(guò)AOP攔截所有service方法,在方法執(zhí)行之前獲取方法上的注解:即數(shù)據(jù)源的key值。
package com.ctitc.collect.manage.datasource;import java.lang.reflect.Method; import java.text.MessageFormat;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; /** * 切換數(shù)據(jù)源(不同方法調(diào)用不同數(shù)據(jù)源) */5. 數(shù)據(jù)源配置
假設(shè)我有兩個(gè)庫(kù):業(yè)務(wù)庫(kù)和訂單庫(kù)。先要配置這兩個(gè)數(shù)據(jù)源
- 業(yè)務(wù)數(shù)據(jù)源
- 訂單數(shù)據(jù)源
- dataSource 則是剛剛實(shí)現(xiàn)的DataSourceRouter,且需要指定此類(lèi)的 targetDataSources屬性和 defaultTargetDataSource屬性。
targetDataSources :數(shù)據(jù)源列表,key-value形式,即上面配置的兩個(gè)數(shù)據(jù)源
defaultTargetDataSource:默認(rèn)數(shù)據(jù)源,如果未指定數(shù)據(jù)源 或者指定的數(shù)據(jù)源不存在的話(huà) 默認(rèn)使用這個(gè)數(shù)據(jù)源
6. AOP的順序問(wèn)題
由于我使用的注解式事務(wù),和我們的AOP數(shù)據(jù)源切面有一個(gè)順序的關(guān)系。數(shù)據(jù)源切換必須先執(zhí)行,數(shù)據(jù)庫(kù)事務(wù)才能獲取到正確的數(shù)據(jù)源。所以要明確指定 注解式事務(wù)和 我們AOP數(shù)據(jù)源切面的先后順序。
- 我們數(shù)據(jù)源切換的AOP是通過(guò)注解來(lái)實(shí)現(xiàn)的,只需要在A(yíng)OP類(lèi)上加上一個(gè)order(1)注解即可,其中1代表順序號(hào)。
- 注解式事務(wù)的是通過(guò)xml配置啟動(dòng)
?
?
7. 示例Demo
在每個(gè)service方法前使用@DataSource("數(shù)據(jù)源key")注解即可。
小禮物走一走,來(lái)簡(jiǎn)書(shū)關(guān)注我
作者:heichong
鏈接:https://www.jianshu.com/p/fddcc1a6b2d8
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
轉(zhuǎn)載于:https://www.cnblogs.com/xiaofengfeng/p/9039382.html
總結(jié)
以上是生活随笔為你收集整理的Spring MVC+Mybatis 多数据源配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python - 装饰器
- 下一篇: JavaScript--关于变量提升思考