一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

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

服務器之家 - 編程語言 - Java教程 - Spring配置多個數據源并實現動態切換示例

Spring配置多個數據源并實現動態切換示例

2020-09-07 08:58gaofuqi Java教程

本篇文章主要介紹了Spring配置多個數據源并實現動態切換示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.配置兩個不同的數據源,如下(由于項目使用的是druid數據庫連接,配置可以會復雜點比較):

?
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
<!-- 數據源配置1 -->
  <bean id="testDataSource1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"
   <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${unity.db.jdbc.url}" /> 
   <property name="username" value="${db.login.name}"></property>
   <property name="password" value="${db.login.password}" />
   <property name="filters" value="${db.filters}"></property>
   <property name="maxActive" value="${db.pool.maxActive}"></property>
   <property name="initialSize" value="${db.pool.initialSize}"></property>
   <property name="minIdle" value="${db.pool.minIdle}"></property>
   <property name="maxWait" value="${db.maxWait}"></property>  
   <property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}"></property>
   <property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}"></property>
   <property name="validationQuery" value="${db.validationQuery}"></property>
   <property name="testWhileIdle" value="${db.testWhileIdle}"></property>
   <property name="testOnBorrow" value="${db.testOnBorrow}"></property>
   <property name="testOnReturn" value="${db.testOnReturn}"></property>
   <property name="poolPreparedStatements" value="${db.poolPreparedStatements}"></property>
   <property name="maxOpenPreparedStatements" value="${db.maxOpenPreparedStatements}"></property>
   <!-- 監控數據庫 -->
    <property name="proxyFilters">
      <list>
        <ref bean="log-filter" />
      </list
    </property>
    
 </bean>
?
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
<!-- 數據源配置2 -->
 <bean id="testDataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"
  <property name="driverClassName" value="${db.driver}" />
   <property name="url" value="${pub.db.jdbc.url}" /> 
  <property name="username" value="${db.login.name}"></property>
  <property name="password" value="${db.login.password}" />
  <property name="filters" value="${db.filters}"></property>
  <property name="maxActive" value="${db.pool.maxActive}"></property>
  <property name="initialSize" value="${db.pool.initialSize}"></property>
  <property name="minIdle" value="${db.pool.minIdle}"></property>
  <property name="maxWait" value="${db.maxWait}"></property>  
  <property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}"></property>
  <property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}"></property>
  <property name="validationQuery" value="${db.validationQuery}"></property>
  <property name="testWhileIdle" value="${db.testWhileIdle}"></property>
  <property name="testOnBorrow" value="${db.testOnBorrow}"></property>
  <property name="testOnReturn" value="${db.testOnReturn}"></property>
  <property name="poolPreparedStatements" value="${db.poolPreparedStatements}"></property>
  <property name="maxOpenPreparedStatements" value="${db.maxOpenPreparedStatements}"></property>
  <!-- 監控數據庫 -->
   <property name="proxyFilters">
     <list>
       <ref bean="log-filter" />
     </list
   </property>
   
</bean>

2.定義一個類繼承AbstractRoutingDataSource實現determineCurrentLookupKey方法,該方法可以實現數據庫的動態切換,如下:

?
1
2
3
4
5
6
public class DynamicDataSource extends AbstractRoutingDataSource {
  @Override
  protected Object determineCurrentLookupKey() {
    return DataSourceContextHolder.getDataSourceType();
  }
}

3.定義一個可以設置當前線程的變量的工具類,用于設置對應的數據源名稱:

?
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
public class DataSourceContextHolder {
  private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
  /**
   * @Description: 設置數據源類型
   * @param dataSourceType 數據庫類型
   * @return void
   * @throws
   */
  public static void setDataSourceType(String dataSourceType) {
    contextHolder.set(dataSourceType);
  }
   
  /**
   * @Description: 獲取數據源類型
   * @param
   * @return String
   * @throws
   */
  public static String getDataSourceType() {
    return contextHolder.get();
  }
   
  /**
   * @Description: 清除數據源類型
   * @param
   * @return void
   * @throws
   */
  public static void clearDataSourceType() {
    contextHolder.remove();
  }
}

然后在spring中配置,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 編寫spring 配置文件的配置多數源映射關系 -->
<bean class="com.sino.access.database.DynamicDataSource" id="dataSource">
  <property name="targetDataSources">
    <map key-type="java.lang.String">
      <entry value-ref="testDataSource1" key="<span style="font-family: Arial, Helvetica, sans-serif;">testDataSource1</span><span style="font-family: Arial, Helvetica, sans-serif;">"></entry></span>
      <entry value-ref="testDataSource2" key="testDataSource2"></entry>
    </map>
  </property>
  <property name="defaultTargetDataSource" ref="testDataSource1">
  </property>
</bean>
 </bean>

這樣配置兩個數據源對應的key分別為testDataSource1和testDataSource2,默認數據庫是testDataSource。

4.完成以上步驟后,如果沒有數據庫的事務管理,已經可以實現數據庫的動態切換了。但是如果涉及到數據庫的事務管理,需要在數據庫事務開啟切換數據庫,

否則數據庫的切換只能在下次數據庫操作時才生效。可以定義一個aop處理類在數據庫事務開啟之前切換數據庫,如下:

?
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
public class DataSourceAspect implements MethodBeforeAdvice,AfterReturningAdvice 
{
 
  @Override
  public void afterReturning(Object returnValue, Method method,
      Object[] args, Object target) throws Throwable {
    // TODO Auto-generated method stub
    DataSourceContextHolder.clearDataSourceType();
  }
 
  @Override
  public void before(Method method, Object[] args, Object target)
      throws Throwable {
   
    if (method.isAnnotationPresent(DataSource.class)) 
    {
      DataSource datasource = method.getAnnotation(DataSource.class);
      DataSourceContextHolder.setDataSourceType(datasource.name());
    }
    else
    {
      DataSourceContextHolder.setDataSourceType(SinoConstant.DataSourceType.unityDataSource.toString());
    }
     
  }
}

5.設置數據庫事務切面和切換數據庫切面執行的順序,如下:

?
1
2
3
4
5
6
<aop:config>
  <aop:pointcut id="transactionPointCut" expression="execution(* com.test.service.*.*(..))" />
  <aop:advisor pointcut-ref="transactionPointCut"
    advice-ref="txAdvice" order="2" />
  <aop:advisor advice-ref="dataSourceExchange" pointcut-ref="transactionPointCut" order="1"/>
</aop:config>

利用aop的order屬性設置執行的順序,這樣實現了帶事務管理的spring數據庫動態切換。

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

原文鏈接:http://blog.csdn.net/gaofuqi/article/details/46417281

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 114级毛片免费观看 1024亚洲天堂 | 久久一本岛在免费线观看2020 | 女人叉开腿让男人捅 | 欧美贵妇vs高跟办公室 | 调教催眠| 欧美精品一区二区三区免费播放 | 亚洲国产黄色 | 美女大乳被捏羞羞漫画 | 亚洲国产精品热久久 | 国产剧情麻豆刘玥视频 | 亚洲国产精品一在线观看 | 天天综合网天天做天天受 | 男女肉粗暴进来下面好紧 | 久久久精品国产免费A片胖妇女 | 日本黄色一区 | 国产精品探花一区在线观看 | 俄罗斯一级大片 | 国内精品久久久久久中文字幕 | 男人j放进女人的p视频免费 | 222aaa精品影院 | 波多野结衣女老师 | 猫咪maomiav永久网址 | 天堂网在线.www天堂在线视频 | 日本九九热 | 国产成人免费观看在线视频 | 久久人妻少妇嫩草AV無碼 | 毛片免费毛片一级jjj毛片 | 2021国产麻豆剧传媒新片 | 亚洲免费闲人蜜桃 | 国产91页 | 四虎影院新网址 | 欧美女孩13一14v | 免费观看欧美性一级 | 亚洲国产一区二区三区青草影视 | 亚洲激情 欧美 | 婷婷综合七月激情啪啪 | jizz漫画| 扒开双腿疯狂进出爽爽动态图 | 欧美亚洲一区二区三区 | 女人爽到喷水的视频免费看 | 色怡红院 |