国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring動態數據源實現讀寫分離詳解

Spring動態數據源實現讀寫分離詳解

2020-12-01 14:22二十六度半 Java教程

這篇文章主要為大家詳細介紹了Spring動態數據源實現讀寫分離,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、創建基于ThreadLocal的動態數據源容器,保證數據源的線程安全性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.bounter.mybatis.extension;
 
/**
 * 基于ThreadLocal實現的動態數據源容器,保證DynamicDataSource的線程安全性
 * @author simon
 *
 */
public class DynamicDataSourceHolder {
 
 private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<>();
 
 public static void setDataSource(String dataSourceKey) {
 dataSourceHolder.set(dataSourceKey);
 }
 
 public static String getDataSource() {
 return dataSourceHolder.get();
 }
 
 public static void clearDataSource() {
 dataSourceHolder.remove();
 }
}

二、定義Spring動態數據源擴展類,用來實現Master、Slave數據源動態切換

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.bounter.mybatis.extension;
 
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
/**
 * 自定義的Spring 動態數據源擴展類,用來實現Master、Slave數據源動態切換
 * @author simon
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
 
 @Override
 protected Object determineCurrentLookupKey() {
 //使用DynamicDataSourceHolder保證線程安全
 return DynamicDataSourceHolder.getDataSource();
 }
 
}

三、配置Master、Slave數據源

1. db.properties配置Master、Slave數據信息

?
1
2
3
4
5
6
7
8
9
10
11
# Master DB
db.master.url=jdbc:mysql://192.168.168.110:3306/bounter?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
db.master.username=bounter
# AES encrypt,Base64 encode
db.master.password=ZNhnEjauk3pecZxxS84ofA==
 
# Slave DB
db.slave.url=jdbc:mysql://192.168.168.111:3306/database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=PRC&useSSL=false
db.slave.username=bounter
# AES encrypt,Base64 encode
db.slave.password=jFYmt2f57RHhzItYDhWiSA==
 

2. Spring 配置文件配置Master、Slave連接池,動態數據源

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<!-- Master數據源 -->
<bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"
 init-method="init" destroy-method="close">
 <!-- 基本屬性 url、user、password -->
 <property name="url" value="${db.master.url}" />
 <property name="username" value="${db.master.username}" />
 <property name="password" value="${db.master.password}" />
 <!-- 配置初始化大小、最小、最大 -->
 <property name="initialSize" value="20" />
 <property name="minIdle" value="1" />
 <property name="maxActive" value="40" />
 <!-- 配置獲取連接等待超時的時間 -->
 <property name="maxWait" value="60000" />
 <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 -->
 <property name="timeBetweenEvictionRunsMillis" value="60000" />
 <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
 <property name="minEvictableIdleTimeMillis" value="300000" />
 <property name="validationQuery" value="SELECT 'x'" />
 <property name="testWhileIdle" value="true" />
 <property name="testOnBorrow" value="false" />
 <property name="testOnReturn" value="false" />
 <!-- 配置監控統計攔截的filters -->
 <property name="filters" value="stat" />
</bean>
 
<!-- Slave數據源 -->
<bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource"
 init-method="init" destroy-method="close">
 <!-- 基本屬性 url、user、password -->
 <property name="url" value="${db.slave.url}" />
 <property name="username" value="${db.slave.username}" />
 <property name="password" value="${db.slave.password}" />
 <!-- 配置初始化大小、最小、最大 -->
 <property name="initialSize" value="20" />
 <property name="minIdle" value="1" />
 <property name="maxActive" value="40" />
 <!-- 配置獲取連接等待超時的時間 -->
 <property name="maxWait" value="60000" />
 <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 -->
 <property name="timeBetweenEvictionRunsMillis" value="60000" />
 <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
 <property name="minEvictableIdleTimeMillis" value="300000" />
 <property name="validationQuery" value="SELECT 'x'" />
 <property name="testWhileIdle" value="true" />
 <property name="testOnBorrow" value="false" />
 <property name="testOnReturn" value="false" />
 <!-- 配置監控統計攔截的filters -->
 <property name="filters" value="stat" />
</bean>
 
<!-- 自定義動態數據源 -->
 <bean id="dataSource" class="com.bounter.mybatis.extension.DynamicDataSource">
 <property name="targetDataSources">
  <map key-type="java.lang.String">
  <!-- 配置讀寫數據源 -->
  <entry value-ref="masterDataSource" key="write"></entry>
  <entry value-ref="slaveDataSource" key="read"></entry>
  </map>
 </property>
 <property name="defaultTargetDataSource" ref="masterDataSource"></property>
 </bean>

四、創建數據源切面,通過AOP實現根據Dao層方法前綴動態選取讀、寫數據源

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.bounter.mybatis.aop;
 
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.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
 
import com.bounter.mybatis.extension.DynamicDataSourceHolder;
 
/**
 * 數據源切面,通過dao方法前綴決定訪問讀、寫數據源
 * @author simon
 *
 */
@Component
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DataSourceAspect {
 
 //讀庫數據源key
 private static final String DATASOURCE_KEY_READ = "read";
 //查詢方法清單
 String[] queryMethods = {"find","get","query","count","select"};
 
 /**
 * dao層方法執行前選擇數據源
 * @param point
 */
 @Before("execution(* com.bounter.mybatis.dao..*.*(..))")
 public void before(JoinPoint point) {
 // 獲取到當前執行的方法名
 String methodName = point.getSignature().getName();
 //匹配查詢方法
 for(String queryMethod : queryMethods) {
  if(methodName.startsWith(queryMethod)) {
  //查詢方法設置數據源為讀庫
  DynamicDataSourceHolder.setDataSource(DATASOURCE_KEY_READ);
  break;
  }
 }
 }
 
 /**
 * dao層方法執行完后清空數據源選擇
 * @param point
 */
 @After("execution(* com.bounter.mybatis.dao..*.*(..))")
 public void after(JoinPoint point) {
 DynamicDataSourceHolder.clearDataSource();
 }
}

github源碼地址:https://github.com/13babybear/bounter-mybatis

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 欧美大片一区 | 日韩在线小视频 | 午夜影院在线观看 | 精品久久久av | 国产精品网站在线观看 | 亚洲在线中文字幕 | 一区视频 | 欧美一级片 | 激情久久久 | 国产视频一区二区三区在线观看 | 不卡视频一区二区 | 自拍偷拍 国产 | 欧美 中文字幕 | 亚洲精品乱码8久久久久久日本 | 精品96久久久久久中文字幕无 | 亚洲成人三级 | 天天干夜夜操 | 欧美久久久 | 欧美区 日韩区 | 国产日韩久久 | 成人免费在线观看 | 成人免费网站在线 | 久久久久久久成人 | 成年人毛片在线观看 | 国产综合欧美 | 国产特黄一级 | 午夜精品一区二区三区在线播放 | 亚洲自拍偷拍精品 | 亚洲男人天堂 | 日韩成人在线看 | 精品国产99 | 一级做a爰片性色毛片2021 | 隔壁老王国产在线精品 | 一区二区三区高清 | 久久久久久国产精品 | 午夜看片在线观看 | 亚洲精品一区二区三区四区高清 | 欧美在线观看免费观看视频 | 欧美在线一区二区 | 福利在线观看 | 1000部精品久久久久久久久 |