spring中怎么通過注解切換多數(shù)據(jù)源,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
開平網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
第一步,配置數(shù)據(jù)源
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root" /> <property name="password" value="spring" /> <property name="url" value="jdbc:MySQL://localhost:3306/taotao?characterEncoding=utf-8" /> <!-- 最大并發(fā)連接數(shù) --> <property name="maxActive" value="30" /> <!-- 最小空閑連接數(shù) --> <property name="minIdle" value="5" /> <!-- 用于顯示數(shù)據(jù)源監(jiān)控中的sql語句監(jiān)控 --> <property name="filters" value="stat" /> </bean> <bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root" /> <property name="password" value="spring" /> <property name="url" value="jdbc:mysql://localhost:3306/taobao?characterEncoding=utf-8" /> <!-- 最大并發(fā)連接數(shù) --> <property name="maxActive" value="30" /> <!-- 最小空閑連接數(shù) --> <property name="minIdle" value="5" /> <!-- 用于顯示數(shù)據(jù)源監(jiān)控中的sql語句監(jiān)控 --> <property name="filters" value="stat" /> </bean>
第二步,定義用來切庫的注解,和枚舉類
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Dataswitch { Datatype value() default Datatype.master; } public enum Datatype { master("masterDataSource"),slave("slaveDataSource"); private String value; Datatype(String name){ this.value = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
第三步,定義一個當(dāng)前線程的變量的工具類,用于設(shè)置對應(yīng)的數(shù)據(jù)源名稱
public class DynamicDataSourceHolder { private static final ThreadLocal<String> threadLocal = new ThreadLocal<String>(); public static String getThreadLocal() { return threadLocal.get(); } public static void setThreadLocal(String name) { threadLocal.set(name); } public static void clear(){ threadLocal.remove(); } }
第四步,創(chuàng)建AbstactRoutingDataSource的子類,重寫determineCurrentLockupKey方法
public class DynamicDataSource extends AbstractRoutingDataSource{ protected Object determineCurrentLookupKey() { System.out.println(DynamicDataSourceHolder.getThreadLocal()); return DynamicDataSourceHolder.getThreadLocal(); } }
第五步,將多數(shù)據(jù)源配置到用我們創(chuàng)建的DynamicDataSource
<bean id="dynamicDataSource" class="xin.youhuila.sorceswitch.process.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="masterDataSource" value-ref="masterDataSource"></entry> <entry key="slaveDataSource" value-ref="slaveDataSource"></entry> </map> </property> <property name="defaultTargetDataSource" ref="masterDataSource"></property> </bean>
第六步,配置切面,在操作數(shù)據(jù)庫方法之前,獲取注解配置的數(shù)據(jù)源名稱,返回
@Component @Aspect @Order(0) public class DataSourceAspect { @Pointcut("execution (* xin.youhuila.sorceswitch.service..*(..))") public void aspect(){ } @Before("aspect()") public void before(JoinPoint joinPoint){ Class<?> clazz = joinPoint.getTarget().getClass(); Method[] method = clazz.getMethods(); Dataswitch dataswitch = null; boolean is = false; for(Method m:method){//此處最好改成通過簽名獲取調(diào)用方法是否含有注解,而不是遍歷每個方法,可參考http://www.gitout.cn/?p=2398 if(m.isAnnotationPresent(Dataswitch.class)){ dataswitch = m.getAnnotation(Dataswitch.class); DynamicDataSourceHolder.setThreadLocal(dataswitch.value().getValue()); is = true; } } if(!is){ DynamicDataSourceHolder.setThreadLocal(Datatype.master.getValue()); } } @After("aspect()") public void after(){ DynamicDataSourceHolder.clear(); } }
第七步,使用
@Service public class DemoService { @Autowired DemoMapper demoMapper; @Dataswitch(Datatype.master) public void select(){ List<Demo> d = demoMapper.select(); for(Demo demo:d){ System.out.println(demo); } } }
--------------------------------http://www.gitout.cn/?p=2398文章實(shí)現(xiàn)-----------------------
/** * 數(shù)據(jù)源切面 */ @Aspect @Component public class DynamicDataSourceAspect { @Pointcut("@annotation(com...datasource.DynamicDataSourceAnnotation)") public void pointCut() { } @Before("pointCut()") public void testBefore(JoinPoint point) { // 獲得當(dāng)前訪問的class Class<?> className = point.getTarget().getClass(); DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class); String dataSource = DataSourceConst.DB_ACTIVITY; // 優(yōu)先級: 方法 > 類 > DB_ACTIVITY if(dataSourceAnnotation != null) { dataSource = dataSourceAnnotation.dataSource(); } String methodName = point.getSignature().getName(); // 得到方法的參數(shù)的類型 Class<?>[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes(); try { Method method = className.getMethod(methodName, argClass); if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) { DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class); dataSource = annotation.dataSource(); } } catch (Exception e) { e.printStackTrace(); } DataSourceContextHolder.setDataSourceType(dataSource); } @After("pointCut()") public void testAfter(JoinPoint point) { // 獲得當(dāng)前訪問的class Class<?> className = point.getTarget().getClass(); DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class); if (dataSourceAnnotation != null) { // 獲得訪問的方法名 String methodName = point.getSignature().getName(); // 得到方法的參數(shù)的類型 Class<?>[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes(); String dataSource = DataSourceConst.DB_ACTIVITY; try { Method method = className.getMethod(methodName, argClass); if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) { DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class); dataSource = annotation.dataSource(); } } catch (Exception e) { e.printStackTrace(); } if (dataSource != null && !DataSourceConst.DB_ACTIVITY.equals(dataSource)) { DataSourceContextHolder.clearDataSourceType(); } } } }
關(guān)于spring中怎么通過注解切換多數(shù)據(jù)源問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。
本文名稱:spring中怎么通過注解切換多數(shù)據(jù)源
新聞來源:http://muchs.cn/article2/ihssic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司、微信公眾號、網(wǎng)站策劃、云服務(wù)器、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)