最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解

 更新時間:2019年11月26日 15:20:47   作者:Java碎碎念  
這篇文章主要介紹了SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

最近公司一個項目需要連接兩個數(shù)據(jù)庫(A和B)操作,有的模塊查詢A庫,有的模塊查詢B庫,因此需要改造下,項目后臺用的是SpringMVC+Mybatis+MySQL架構(gòu),折騰了兩天后終于搞定了,在這里記錄過改造過程。

使用場景

多數(shù)據(jù)源的使用的場景一般有:

  • 主從數(shù)據(jù)庫切換
  • 讀寫分離
  • 兼容舊庫

實(shí)現(xiàn)原理

Spring2.x的版本中采用Proxy模式,就是在方案中實(shí)現(xiàn)一個虛擬的數(shù)據(jù)源,并且用它來封裝數(shù)據(jù)源選擇邏輯,這樣就可以有效地將數(shù)據(jù)源選擇邏輯從Client中分離出來。Client提供選擇所需的上下文,由虛擬的DynamicDataSource根據(jù)Client提供的上下文來實(shí)現(xiàn)數(shù)據(jù)源的選擇。

具體的實(shí)現(xiàn)是虛擬的DynamicDataSource僅需繼承AbstractRoutingDataSource實(shí)現(xiàn)determineCurrentLookupKey(),該方法返回需要使用的DataSource的key值,然后根據(jù)這個key從resolvedDataSources這個map里取出對應(yīng)的DataSource,如果找不到則用默認(rèn)的resolvedDefaultDataSource。

詳細(xì)實(shí)現(xiàn)過程

修改spring的配置文件

配置文件里需要配置多個數(shù)據(jù)源,改造后主要配置如下:

  <bean id="dataSourceTargetA" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close" scope="singleton">
    <property name="driverClass" value="${jdbc.a.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.a.url}" />
    <property name="user" value="${jdbc.a.username}" />
    <property name="password" value="${jdbc.a.password}" />
    <!--當(dāng)連接池中的連接耗盡的時候c3p0一次同時獲取的連接數(shù)。Default: 3 -->
    <property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
    <!--初始化時獲取三個連接,取值應(yīng)在minPoolSize與maxPoolSize之間。Default: 3 -->
    <property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
    <!--最大空閑時間,60秒內(nèi)未使用則連接被丟棄。若為0則永不丟棄。Default: 0 -->
    <property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
    <!--連接池中保留的最大連接數(shù)。Default: 15 -->
    <property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
    <property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
    <!--兩次連接中間隔時間,單位毫秒。Default: 1000 -->
    <property name="acquireRetryDelay" value="1000"></property>
    <!--定義在從數(shù)據(jù)庫獲取新連接失敗后重復(fù)嘗試的次數(shù)。Default: 30 -->
    <property name="acquireRetryAttempts" value="60"></property>
    <!--獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數(shù)據(jù)源仍有效保留,并在下次調(diào)用getConnection()的時候繼續(xù)嘗試獲取連接。如果設(shè)為true,那么在嘗試獲取連接失敗后該數(shù)據(jù)源將申明已斷開并永久關(guān)閉。Default:
      false -->
    <property name="breakAfterAcquireFailure" value="false"></property>
  </bean>

  <bean id="dataSourceTargetB" class="com.mchange.v2.c3p0.ComboPooledDataSource"
     destroy-method="close" scope="singleton">
    <property name="driverClass" value="${jdbc.b.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.b.url}" />
    <property name="user" value="${jdbc.b.username}" />
    <property name="password" value="${jdbc.b.password}" />
    <!--當(dāng)連接池中的連接耗盡的時候c3p0一次同時獲取的連接數(shù)。Default: 3 -->
    <property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
    <!--初始化時獲取三個連接,取值應(yīng)在minPoolSize與maxPoolSize之間。Default: 3 -->
    <property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
    <!--最大空閑時間,60秒內(nèi)未使用則連接被丟棄。若為0則永不丟棄。Default: 0 -->
    <property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
    <!--連接池中保留的最大連接數(shù)。Default: 15 -->
    <property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
    <property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
    <!--兩次連接中間隔時間,單位毫秒。Default: 1000 -->
    <property name="acquireRetryDelay" value="1000"></property>
    <!--定義在從數(shù)據(jù)庫獲取新連接失敗后重復(fù)嘗試的次數(shù)。Default: 30 -->
    <property name="acquireRetryAttempts" value="60"></property>
    <!--獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數(shù)據(jù)源仍有效保留,并在下次調(diào)用getConnection()的時候繼續(xù)嘗試獲取連接。如果設(shè)為true,那么在嘗試獲取連接失敗后該數(shù)據(jù)源將申明已斷開并永久關(guān)閉。Default:
      false -->
    <property name="breakAfterAcquireFailure" value="false"></property>
  </bean>
  <!-- 動態(tài)數(shù)據(jù)源 -->
  <bean id="dynamicDataSource" class="com.test.util.DynamicDataSource" >
    <property name="targetDataSources">
      <map key-type="java.lang.String">
        <entry value-ref="dataSourceTargetA" key="dataSourceTargetA"></entry>
        <entry value-ref="dataSourceTargetB" key="dataSourceTargetB"></entry>
      </map>
    </property>
    <property name="defaultTargetDataSource" ref="dataSourceTargetA" >
    </property>
  </bean>
  

  <bean id="txManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dynamicDataSource" />
  </bean>
  

  <!-- MyBatis ORM operation class -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dynamicDataSource" />
    <property name="mapperLocations">
      <list>
        <value>classpath*:com/test/**/*Mapper.xml</value>
      </list>
    </property>
    <property name="configLocation" value="classpath:provider-sql-map-config.xml" />
  </bean>

添加動態(tài)數(shù)據(jù)源管理類

DynamicDataSource類繼承AbstractRoutingDataSource,實(shí)現(xiàn)determineCurrentLookupKey()方法。

package com.test.util;
import com.test.util.CustomerContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 動態(tài)數(shù)據(jù)源管理類
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

  @Override
  protected Object determineCurrentLookupKey() {
    return CustomerContextHolder.getCustomerType();
  }
}

數(shù)據(jù)源切換類

CustomerContextHolder類可以實(shí)現(xiàn)數(shù)據(jù)源A和B的切換,數(shù)據(jù)源標(biāo)識保存在線程變量中,避免多線程操作數(shù)據(jù)源時互相干擾

package com.test.util;
/**
 * 數(shù)據(jù)源切換類
 *
 */
public class CustomerContextHolder {
  public static final String DATA_SOURCE_DEFAULT = "dataSourceTargetA";
  public static final String DATA_SOURCE_B = "dataSourceTargetB";
  private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
  public static void setCustomerType(String customerType) {
    contextHolder.set(customerType);
  }
  public static String getCustomerType() {
    return contextHolder.get();
  }
  public static void clearCustomerType() {
    contextHolder.remove();
  }
}

使用多數(shù)據(jù)源代碼

下面是Controller層代碼,需要查詢B數(shù)據(jù)源,查詢完成后切換為默認(rèn)數(shù)據(jù)源A,具體代碼如下:

/**
   * 訂單列表查詢,查詢B數(shù)據(jù)源
   *
   * @param request
   * @return
   */
  @RequestMapping(value = "/list")
  public String list(HttpServletRequest request, Integer cId) {
    //設(shè)置數(shù)據(jù)源B
    CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);
    List<Order> orderList = salaryBillService.getSalaryOrderByOrgId(cId);
    request.setAttribute("orderList", orderList);
    //切換回默認(rèn)數(shù)據(jù)源A
    CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_DEFAULT);
    return "/jsp/order";
  }

上述四步操作完成后即可實(shí)現(xiàn)SpringMVC+Mybatis配置多個數(shù)據(jù)源并切換,有問題歡迎留言溝通哦!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot 接口開發(fā)教程(httpclient客戶端)

    SpringBoot 接口開發(fā)教程(httpclient客戶端)

    這篇文章主要介紹了SpringBoot 接口開發(fā)教程(httpclient客戶端),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java中正則表達(dá)式的語法以及matches方法的使用方法

    Java中正則表達(dá)式的語法以及matches方法的使用方法

    正則表達(dá)式(Regular Expression)是一門簡單語言的語法規(guī)范,是強(qiáng)大、便捷、高效的文本處理工具,這篇文章主要給大家介紹了關(guān)于Java中正則表達(dá)式的語法以及matches方法的使用方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • Java語言簡介(動力節(jié)點(diǎn)Java學(xué)院整理)

    Java語言簡介(動力節(jié)點(diǎn)Java學(xué)院整理)

    Java是一門面向?qū)ο缶幊陶Z言,不僅吸收了C++語言的各種優(yōu)點(diǎn),還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強(qiáng)大和簡單易用兩個特征,下面通過本文給大家分享java語言的簡介,感興趣的朋友一起看看吧
    2017-03-03
  • 深入理解final變量的初始化

    深入理解final變量的初始化

    本篇文章是對final變量的初始化進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • maven打包zip包含bin下啟動腳本的完整代碼

    maven打包zip包含bin下啟動腳本的完整代碼

    這篇文章主要介紹了maven打包zip包含bin下啟動腳本,本文給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • spring boot @PathVariable傳遞帶反斜杠參數(shù) / 的處理

    spring boot @PathVariable傳遞帶反斜杠參數(shù) / 的處理

    這篇文章主要介紹了spring boot @PathVariable傳遞帶反斜杠參數(shù) / 的處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Springboot內(nèi)嵌SQLite配置使用詳解

    Springboot內(nèi)嵌SQLite配置使用詳解

    這篇文章主要介紹了Springboot內(nèi)嵌SQLite配置使用詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java設(shè)計模式之工廠模式實(shí)現(xiàn)方法詳解

    Java設(shè)計模式之工廠模式實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了Java設(shè)計模式之工廠模式實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了工廠模式的分類、原理、實(shí)現(xiàn)方法與相關(guān)注意事項,需要的朋友可以參考下
    2017-12-12
  • 基于SpringBoot服務(wù)端表單數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)方式

    基于SpringBoot服務(wù)端表單數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)方式

    這篇文章主要介紹了基于SpringBoot服務(wù)端表單數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • mybatis-sqlserver批量新增返回id方式

    mybatis-sqlserver批量新增返回id方式

    這篇文章主要介紹了mybatis-sqlserver批量新增返回id方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評論

鹤岗市| 南通市| 井冈山市| 莎车县| 宁安市| 昭平县| 高碑店市| 鸡东县| 新昌县| 新沂市| 松滋市| 义乌市| 慈利县| 绥中县| 肇州县| 郁南县| 宜州市| 泰州市| 化州市| 滕州市| 双牌县| 乐昌市| 揭阳市| 辉南县| 昌黎县| 南漳县| 洛川县| 玉林市| 江华| 西乌珠穆沁旗| 达拉特旗| 灵石县| 紫金县| 韶关市| 明星| 兰溪市| 云浮市| 湟源县| 绥宁县| 永嘉县| 三门县|