激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

服務器之家 - 編程語言 - Java教程 - mysql+spring+mybatis實現數據庫讀寫分離的代碼配置

mysql+spring+mybatis實現數據庫讀寫分離的代碼配置

2021-07-20 16:45小飛俠-2 Java教程

今天小編就為大家分享一篇關于mysql+spring+mybatis實現數據庫讀寫分離的代碼配置,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

場景:一個讀數據源一個讀寫數據源。

原理:借助spring的【org.springframework.jdbc.datasource.lookup.abstractroutingdatasource】這個抽象類實現,看名字可以了解到是一個路由數據源的東西,這個類中有一個方法

?
1
2
3
4
5
6
7
8
/**
 * determine the current lookup key. this will typically be
 * implemented to check a thread-bound transaction context.
 * <p>allows for arbitrary keys. the returned key needs
 * to match the stored lookup key type, as resolved by the
 * {@link #resolvespecifiedlookupkey} method.
 */
protected abstract object determinecurrentlookupkey();

每次去連數據庫的時候,spring會調用這個方法去找對應的數據源。返回值即對應的數據源的lookupkey.那么這個lookupkey在哪定義的呢?看下面的database.xml的配置

?
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
<!--數據源 讀寫 -->
<bean id="datasourcerw" class="org.logicalcobwebs.proxool.proxooldatasource">
  <property name="alias" value="ihotelrw"></property>
  <property name="delegateproperties">
    <value>user=${jdbc.username},password=${jdbc.password}
    </value>
  </property>
  <property name="user" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
  <property name="driver" value="${jdbc.driverclassname}" />
  <property name="driverurl" value="${jdbc.url}" />
  <property name="maximumconnectioncount" value="${jdbc.maximumconnectioncount}"></property>
  <property name="maximumactivetime" value="${jdbc.maximumactivetime}"></property>
  <property name="maximumconnectionlifetime" value="${jdbc.maximumconnectionlifetime}"></property>
  <property name="prototypecount" value="${jdbc.prototypecount}"></property>
  <property name="housekeepingsleeptime" value="${jdbc.housekeepingsleeptime}"></property>
  <property name="simultaneousbuildthrottle" value="${jdbc.simultaneousbuildthrottle}"></property>
  <property name="housekeepingtestsql" value="${jdbc.housekeepingtestsql}"></property>
  <property name="verbose" value="${jdbc.verbose}"></property>
  <property name="statistics" value="${jdbc.statistics}"></property>
  <property name="statisticsloglevel" value="${jdbc.statisticsloglevel}"></property>
</bean>
  <!--數據源 讀-->
  <bean id="datasourcer" class="org.logicalcobwebs.proxool.proxooldatasource">
    <property name="alias" value="ihotelr"></property>
    <property name="delegateproperties">
      <value>user=${jdbc.r.username},password=${jdbc.r.password}
      </value>
    </property>
    <property name="user" value="${jdbc.r.username}" />
    <property name="password" value="${jdbc.r.password}" />
    <property name="driver" value="${jdbc.r.driverclassname}" />
    <property name="driverurl" value="${jdbc.r.url}" />
    <property name="maximumconnectioncount" value="${jdbc.maximumconnectioncount}"></property>
    <property name="maximumactivetime" value="${jdbc.maximumactivetime}"></property>
    <property name="maximumconnectionlifetime" value="${jdbc.maximumconnectionlifetime}"></property>
    <property name="prototypecount" value="${jdbc.prototypecount}"></property>
    <property name="housekeepingsleeptime" value="${jdbc.housekeepingsleeptime}"></property>
    <property name="simultaneousbuildthrottle" value="${jdbc.simultaneousbuildthrottle}"></property>
    <property name="housekeepingtestsql" value="${jdbc.housekeepingtestsql}"></property>
    <property name="verbose" value="${jdbc.verbose}"></property>
    <property name="statistics" value="${jdbc.statistics}"></property>
    <property name="statisticsloglevel" value="${jdbc.statisticsloglevel}"></property>
  </bean>
  <!-- 動態數據源 -->
  <bean id="dynamicdatasource" class="com.dao.datasource.dynamicdatasource">
    <!-- 通過key-value關聯數據源 -->
    <property name="targetdatasources">
      <map>
        <entry value-ref="datasourcerw" key="datasourcekeyrw"></entry>
        <entry value-ref="datasourcer" key="datasourcekeyr"></entry>
      </map>
    </property>
    <property name="defaulttargetdatasource" ref="datasourcerw" />  
  </bean>
<!--mybatis與spring整合 開始 -->
<bean id="sqlsessionfactory" name="sqlsessionfactory"
  class="org.mybatis.spring.sqlsessionfactorybean">
  <property name="configlocation" value="classpath:conf/core/sqlmapconfig.xml" />
  <property name="datasource" ref="dynamicdatasource" />
</bean>

動態數據源dynamicdatasource中的datasourcekeyrw、datasourcekeyr就是

?
1
protected abstract object determinecurrentlookupkey();

這個方法要返回的值。那么如何設置,讓這個方法的返回值是根據我們的需要返回datasourcekeyrw、datasourcekeyr呢?由于這個方法沒有入參,并且是spring自動調用的,因此考慮使用靜態變量存儲datasource的key,在調用sql語句前設置靜態變量的值,然后在這個方法中得到靜態變量的值,返回。又考慮到多線程,同時可能會有很多請求,為避免線程之間相互干擾,考慮使用threadlocal。

先看存儲datasourcekey的容器類。

?
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 dbcontextholder {
  /**
   * 線程threadlocal
   */
  private static threadlocal<string> contextholder = new threadlocal<>();
  private string db_type_rw = "datasourcekeyrw";
  private string db_type_r = "datasourcekeyr";
  public string getdbtype() {
    string db = contextholder.get();
    if (db == null) {
      db = db_type_rw;// 默認是讀寫庫
    }
    return db;
  }
  /**
   * 設置本線程的dbtype
   * @param str
   * @see [相關類/方法](可選)
   * @since [產品/模塊版本](可選)
   */
  public void setdbtype(string str) {
    contextholder.set(str);
  }
  /**
   * cleardbtype
   * @title: cleardbtype
   * @description: 清理連接類型
   */
  public static void cleardbtype() {
    contextholder.remove();
  }
}

動態數據源的實現類。

?
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
public class dynamicdatasource extends abstractroutingdatasource {
  /*
   * (non-javadoc)
   * @see javax.sql.commondatasource#getparentlogger()
   */
  @override
  public logger getparentlogger() throws sqlfeaturenotsupportedexception {
    // todo auto-generated method stub
    return null;
  }
  /**
   * override determinecurrentlookupkey
   * <p>
   * title: determinecurrentlookupkey
   * </p>
   * <p>
   * description: 自動查找datasource
   * </p>
   * @return
   */
  @override
  protected object determinecurrentlookupkey() {
    return dbcontextholder.getdbtype();
  }
}

在dao層中設置數據庫類型。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
   * 添加郵件
   * @param sms
   * @return
   */
  public boolean insertemail(email email) {
    //根據具體需要設置不同的數據庫
    dbcontextholder.setdbtype(dbcontextholder.db_type_rw);
    //dbcontextholder.setdbtype(dbcontextholder.db_type_r);
    int result = this.getsqlsession().insert(statement + ".addentity",
        email);
    return result == 1;
  }

在本例中,我們是在dao中指定數據庫,我們也可以根據需要在service或者controller中指定db類型,需要記住的是setdbtype是針對線程維度的。要考慮多線程的問題。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

原文鏈接:https://blog.csdn.net/qq_26562641/article/details/64122643

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人综合区一区 | 在线看一区二区三区 | 久久96国产精品久久久 | 特级无码毛片免费视频尤物 | 久久国产乱子伦精品 | 草碰人人 | 亚洲免费在线视频 | 国产精品亚洲欧美一级在线 | 蜜桃视频在线观看视频 | 国产在线地址 | 一区国产在线观看 | 久久精品国产一区二区 | 黄色小视频免费在线观看 | 国产精品99久久免费观看 | 精品国产第一区二区三区 | 国产免费人做人爱午夜视频 | 欧美一级毛片欧美一级成人毛片 | 一级毛片免费高清视频 | 国av在线 | 国产福利视频在线观看 | 欧美 国产 亚洲 卡通 综合 | 2023av在线视频 | 黄色免费av| 激情大乳女做爰办公室韩国 | 爱高潮www亚洲精品 国产一区二区三区视频免费 | 羞羞网站在线看 | 欧美成人精品欧美一级 | 亚洲第一页综合 | 欧美一区在线观看视频 | 欧美a级毛片| 黄色网址免费入口 | 欧美亚洲免费 | 成人片在线播放 | 久久久www视频 | jizzjizzjizz少妇 | 亚洲电影免费观看高清完整版在线观 | 亚洲生活片 | 永久av在线免费观看 | 日韩视频一 | 免费一级特黄毛片 | 欧美精品一区二区久久 |