国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Spring配置動態數據源實現讀寫分離的方法

2019-11-26 13:13:23
字體:
來源:轉載
供稿:網友

前言

最近因為工作的需要,要搭建的一個項目需要實現數據源的讀寫分離,在這里將代碼進行分享,有需要的朋友們可以參考學習。

首先是配置數據源

<!--讀數據源配置--><bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"destroy-method="close">//配置省略</bean><!--寫數據源配置--><bean id="writeDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"destroy-method="close">//配置省略</bean><!-- 動態數據源 --><bean id = "dataSource" class="com.potato.common.bean.DynamicDataSource" >  <!-- 已配置的數據源 -->  <property name="targetDataSources">   <map>     <entry key="READ" value-ref="readDataSource"/>     <entry key="WRITE" value-ref="writeDataSource"/>   </map>  </property>  <!-- 默認的數據源 -->  <property name="defaultTargetDataSource" ref="writeDataSource"/></bean>

數據源是如何切換的呢?通過動態數據源的配置我們知道原來是通過key來進行切換,這里要使用到org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,我們可以編寫自己的動態數據源類DynamicDataSource來繼承它。

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

還需要一個存放key的地方DataSourceContextHolder 為保證切換時線程安全我們使用ThreadLocal來保存我們的key。

public class DataSourceContextHolder { private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceContextHolder.class); public static final String DATA_SOURCE_WRITE = "WRITE"; public static final String DATA_SOURCE_READ = "READ"; // 線程本地環境 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); // 設置數據源類型 public static void setType(String type) {  if(LOGGER.isDebugEnabled())   LOGGER.debug("==============切換數據源,類型:"+type+"================");  contextHolder.set(type); } // 獲取數據源類型 public static String getType() {  return (contextHolder.get()); } // 清除數據源類型 public static void clearType() {  contextHolder.remove(); }}

好了,我們可以通過操作DataSourceContextHolder來實現數據源動態的切換了。小伙伴們可能會說了,難道每次調用方法都要手動選擇要切換的數據源類型?當然不是啦,Spring AOP登場。

@Component@Aspectpublic class DynamicDataSourceAspect { @Pointcut("execution (* com.potato.orm.mapper.*.select*(..)) || execution (* com.potato.orm.mapper.*.count*(..)) ") public void readMethodPointcut() {} @Pointcut("execution (* com.potato.orm.mapper.*.insert*(..)) || execution (* com.potato.orm.mapper.*.update*(..)) || execution (* com.potato.orm.mapper.*.delete*(..))") public void writeMethodPointcut() {} @Before("readMethodPointcut()") public void switchReadDataSource(){  //System.out.println("============切換到讀數據源===========");  DataSourceContextHolder.setType(DataSourceContextHolder.DATA_SOURCE_READ); } @Before("writeMethodPointcut()") public void switchWriteDataSource(){  //System.out.println("=============切換到寫數據源==========");  DataSourceContextHolder.setType(DataSourceContextHolder.DATA_SOURCE_WRITE); }}

總結

好啦,以上就是這篇文章的全部內容了,在訪問Mapper(本項目使用的是MyBatis啦,相當于是DAO)中查詢方法時會切換到讀數據源,增、刪、改方法會切換到寫數據源。希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宝兴县| 塘沽区| 博爱县| 龙井市| 无为县| 江孜县| 肥乡县| 酒泉市| 潜江市| 水富县| 迭部县| 新乐市| 宣武区| 陆丰市| 和平区| 醴陵市| 建始县| 张掖市| 邵阳市| 新巴尔虎左旗| 铜陵市| 盐池县| 博湖县| 五常市| 芜湖县| 旬邑县| 南昌市| 福鼎市| 碌曲县| 湘西| 北海市| 连城县| 隆化县| 南皮县| 遵义县| 诸城市| 那坡县| 宝兴县| 邵阳市| 盘锦市| 慈溪市|