日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

springboot动态数据源切换(多数据源配置)

發(fā)布時(shí)間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot动态数据源切换(多数据源配置) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

動(dòng)態(tài)數(shù)據(jù)源切換即多數(shù)據(jù)源切換,由于業(yè)務(wù)的需要或者歷史的遺留等原因,一個(gè)項(xiàng)目中配置了多個(gè)數(shù)據(jù)庫,用于查詢不同類型的數(shù)據(jù),因此我們就需要經(jīng)常在各個(gè)庫中切換數(shù)據(jù)源,接下來我們將進(jìn)行具體的說明:

項(xiàng)目結(jié)構(gòu)如下:

相關(guān)類說明:

DynamicDataSource:動(dòng)態(tài)獲取數(shù)據(jù)源的實(shí)現(xiàn),繼承AbstractRoutingDataSource(每執(zhí)行一次數(shù)據(jù)庫,動(dòng)態(tài)獲取DataSource)

DynamicDataSourceContextHolder:動(dòng)態(tài)數(shù)據(jù)源上下文管理,相當(dāng)于在容器中管理數(shù)據(jù)源實(shí)例

DynamicDattaSourceAspect:動(dòng)態(tài)數(shù)據(jù)源通知

TargetDataSource:數(shù)據(jù)源注解,作用于類、接口或者方法上,用于指定數(shù)據(jù)源

DynamicDatasourceConfig:動(dòng)態(tài)數(shù)據(jù)源配置,實(shí)例化所有配置數(shù)據(jù)源

?

具體類實(shí)現(xiàn):

DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceType();} }

DynamicDataSourceContextHolder:

/*** 存放當(dāng)前線程使用的數(shù)據(jù)源類型信息*/private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();/*** 存放數(shù)據(jù)源id,即數(shù)據(jù)源實(shí)例名稱*/public static List<String> dataSourceIds = new ArrayList<String>();/*** 設(shè)置數(shù)據(jù)源** @param dataSourceType*/public static void setDataSourceType(String dataSourceType) {logger.info("添加數(shù)據(jù)源實(shí)例到管理器中,dataSourceType{}", dataSourceType);contextHolder.set(dataSourceType);}/*** 獲取數(shù)據(jù)源** @return*/public static String getDataSourceType() {logger.info("從數(shù)據(jù)源實(shí)例管理器中獲取當(dāng)前實(shí)例");return contextHolder.get();}/*** 清除數(shù)據(jù)源*/public static void clearDataSourceType() {logger.info("清除當(dāng)前數(shù)據(jù)源實(shí)例");contextHolder.remove();}/*** 判斷當(dāng)前數(shù)據(jù)源是否存在** @param dataSourceId* @return*/public static boolean isContainsDataSource(String dataSourceId) {logger.info("判斷當(dāng)前數(shù)據(jù)源是否存在,dataSourceId={}", dataSourceId);return dataSourceIds.contains(dataSourceId);}

DynamicDattaSourceAspect

package com.xiaofeng.datasource2.aspect;import com.xiaofeng.datasource2.aspect.annotation.TargetDataSource; import com.xiaofeng.datasource2.dynamic.DynamicDataSourceContextHolder; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;/*** @author xiaofeng* @version V1.0* @title: DynamicDattaSourceAspect* @package: com.xiaofeng.sys.dynamic* @description: 動(dòng)態(tài)數(shù)據(jù)源通知* @date 2019/8/28 16:48*/ @Aspect @Order(-1) @Component public class DynamicDattaSourceAspect {private Logger logger = LoggerFactory.getLogger(DynamicDattaSourceAspect.class);/*** 改變數(shù)據(jù)源,判斷使用注解中的數(shù)據(jù)源實(shí)例名稱,根據(jù)實(shí)例名稱從上下文管理器中獲取數(shù)據(jù)源** @param joinPoint* @param targetDataSource*/@Before("@annotation(targetDataSource)")public void changeDataSource(JoinPoint joinPoint, TargetDataSource targetDataSource) {logger.info("選擇數(shù)據(jù)源---" + targetDataSource.value().getValue());DynamicDataSourceContextHolder.setDataSourceType(targetDataSource.value().getValue());}/*** 使用完后清理數(shù)據(jù)源** @param joinPoint* @param targetDataSource*/@After("@annotation(targetDataSource)")public void clearDataSource(JoinPoint joinPoint, TargetDataSource targetDataSource) {logger.debug("清除數(shù)據(jù)源 " + targetDataSource.value().getValue() + " !");DynamicDataSourceContextHolder.clearDataSourceType();} }

TargetDataSource

@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource {DataSourceEnum value() default DataSourceEnum.MASTER; }

?

DynamicDatasourceConfig

@Bean(name = "master")@ConfigurationProperties(prefix = "spring.datasource.druid.master")public DataSource master() {return DruidDataSourceBuilder.create().build();}@Bean(name = "slave")@ConfigurationProperties(prefix = "spring.datasource.druid.slave")public DataSource slave() {return DruidDataSourceBuilder.create().build();}/*** 動(dòng)態(tài)數(shù)據(jù)源配置** @return*/@Bean@Primarypublic DataSource multipleDataSource(@Qualifier("master") DataSource master, @Qualifier("slave") DataSource slave) {DynamicDataSource multipleDataSource = new DynamicDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceEnum.MASTER.getValue(), master);targetDataSources.put(DataSourceEnum.SLAVE.getValue(), slave);//添加數(shù)據(jù)源multipleDataSource.setTargetDataSources(targetDataSources);//設(shè)置默認(rèn)數(shù)據(jù)源multipleDataSource.setDefaultTargetDataSource(master);return multipleDataSource;}

測試類如下:

實(shí)現(xiàn)效果如下:

至此我們的多數(shù)據(jù)源配置(主從數(shù)據(jù)源)已完成,此種方式已經(jīng)過親測驗(yàn)證!

可運(yùn)行完整源碼下載地址http://zyshare.cn/resource/detail/10

總結(jié)

以上是生活随笔為你收集整理的springboot动态数据源切换(多数据源配置)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。