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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品国产A久久久久久 亚洲精品福利一区二区在线观看 | 日本又黄又裸一级大黄裸片 | 成年人免费在线看 | 俄罗斯一级成人毛片 | 青柠网在线观看视频 | 狠狠综合视频精品播放 | a级动漫| 无码国产成人777爽死 | 1313午夜精品久久午夜片 | 操美女| 苍井空av| 潘金莲西门庆一级淫片aaaaaa | 国产日韩欧美视频 | 国产精品酒店视频免费看 | 日韩欧美国产成人 | 青春草视频在线免费观看 | 亚洲AV无码国产精品色在线看 | 香蕉久久一区二区三区啪啪 | 午夜小视频免费 | 国产综合久久 | 青苹果乐园影院免费观看完整版 | 午夜福利合集1000在线 | 香蕉tv国产在线永久播放 | 亚洲人成高清毛片 | 四虎永久在线精品波多野结衣 | 精品国产mmd在线观看 | 欧美日韩专区国产精品 | 亚洲国产成人久久77 | 国产亚洲精品美女久久久 | 99综合视频| 国产精品久久久99 | 亚洲欧美天堂综合久久 | 五月色天在线视频综合观看 | 国产亚洲欧美日韩综合综合二区 | 成人小视频在线观看 | 黄www片| 欧美高清乌克兰精品另类 | 国产高清在线观看 | 四虎免费在线观看 | 免费看男女污污完整版 | 欧美se图|