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

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

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

服務器之家 - 編程語言 - Java教程 - 詳解MyBatis多數據源配置(讀寫分離)

詳解MyBatis多數據源配置(讀寫分離)

2020-07-21 11:48isea533 Java教程

這篇文章主要介紹了詳解MyBatis多數據源配置(讀寫分離),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

MyBatis多數據源配置(讀寫分離)

首先說明,本文的配置使用的最直接的方式,實際用起來可能會很麻煩。

實際應用中可能存在多種結合的情況,你可以理解本文的含義,不要死板的使用。

多數據源的可能情況

1.主從

通常是MySQL一主多從的情況,本文的例子就是主從的情況,但是只有兩個數據源,所以采用直接配置不會太麻煩,但是不利于后續擴展,主要是作為一個例子來說明,實際操作請慎重考慮。

2.分庫

當業務獨立性強,數據量大的時候的,為了提高并發,可能會對表進行分庫,分庫后,每一個數據庫都需要配置一個數據源。

這種情況可以參考本文,但是需要注意每一個數據庫對應的Mapper要在不同的包下方便區分和配置。

另外分庫的情況下也會存在主從的情況,如果你的數據庫從庫過多,就參考上面提供的方法,或者尋找其他方式解決。

Mapper分包

分庫的情況下,不同的數據庫的Mapper一定放在不同的包下。

主從的情況下,同一個Mapper會同時存在讀寫的情況,創建兩個并不合適,使用同一個即可。但是這種情況下需要注意,Spring對Mapper自動生成的名字是相同的,而且類型也相同,這是就不能直接注入Mapper接口。需要通過SqlSession來解決。

Spring基礎配置

applicationContext.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <context:component-scan base-package="com.isea533.mybatis.service"/>
  <context:property-placeholder location="classpath:config.properties"/>
  <aop:aspectj-autoproxy/>
 
  <import resource="spring-datasource-master.xml"/>
  <import resource="spring-datasource-slave.xml"/>
</beans>

這個文件,主要是引入了spring-datasource-master.xml和spring-datasource-slave.xml。

spring-datasource-master.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
62
63
64
65
66
67
68
69
70
71
72
73
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="dataSourceMaster" class="com.alibaba.druid.pool.DruidDataSource"
    init-method="init" destroy-method="close">
    <property name="driverClassName" value="${master.jdbc.driverClass}"/>
    <property name="url" value="${master.jdbc.url}"/>
    <property name="username" value="${master.jdbc.user}"/>
    <property name="password" value="${master.jdbc.password}"/>
 
    <property name="filters" value="stat"/>
 
    <property name="maxActive" value="20"/>
    <property name="initialSize" value="1"/>
    <property name="maxWait" value="60000"/>
    <property name="minIdle" value="1"/>
 
    <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"/>
  </bean>
 
  <bean id="sqlSessionFactory1"
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSourceMaster"/>
    <property name="mapperLocations">
      <array>
        <value>classpath:mapper/*.xml</value>
      </array>
    </property>
  </bean>
 
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/>
  </bean>
 
  <bean id="sqlSessionMaster" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="sqlSessionFactory1"/>
  </bean>
 
  <aop:config>
    <aop:pointcut id="appService"
      expression="execution(* com.isea533.mybatis.service..*Service*.*(..))"/>
    <aop:advisor advice-ref="txAdvice1" pointcut-ref="appService"/>
  </aop:config>
 
  <tx:advice id="txAdvice1" transaction-manager="transactionManager1">
    <tx:attributes>
      <tx:method name="select*" read-only="true"/>
      <tx:method name="find*" read-only="true"/>
      <tx:method name="get*" read-only="true"/>
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>
 
  <bean id="transactionManager1"
   class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceMaster"/>
  </bean>
</beans>

spring-datasource-slave.xml

和master區別不大,主要是id名字和數據源配置有區別。

?
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
62
63
64
65
66
67
68
69
70
71
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
 
  <bean id="dataSourceSlave" class="com.alibaba.druid.pool.DruidDataSource"
    init-method="init" destroy-method="close">
    <property name="driverClassName" value="${slave.jdbc.driverClass}"/>
    <property name="url" value="${slave.jdbc.url}"/>
    <property name="username" value="${slave.jdbc.user}"/>
    <property name="password" value="${slave.jdbc.password}"/>
 
    <property name="filters" value="stat"/>
 
    <property name="maxActive" value="20"/>
    <property name="initialSize" value="1"/>
    <property name="maxWait" value="60000"/>
    <property name="minIdle" value="1"/>
 
    <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"/>
  </bean>
 
  <bean id="sqlSessionFactory2"
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSourceSlave"/>
    <property name="mapperLocations">
      <array>
        <value>classpath:mapper/*.xml</value>
      </array>
    </property>
  </bean>
 
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
  </bean>
 
  <bean id="sqlSessionSlave" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="sqlSessionFactory2"/>
  </bean>
 
 
  <aop:config>
    <aop:pointcut id="appService"
      expression="execution(* com.isea533.mybatis.service..*Service*.*(..))"/>
    <aop:advisor advice-ref="txAdvice2" pointcut-ref="appService"/>
  </aop:config>
 
  <tx:advice id="txAdvice2" transaction-manager="transactionManager2">
    <tx:attributes>
      <tx:method name="*" read-only="true"/>
    </tx:attributes>
  </tx:advice>
 
  <bean id="transactionManager2"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSourceSlave"/>
  </bean>
</beans>

這里需要注意<tx:method name="*" read-only="true"/>是只讀的。如果不是從庫,可以按主庫進行配置。

在下面代碼中:

?
1
2
3
4
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="com.isea533.mybatis.mapper"/>
  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
</bean>

必須通過sqlSessionFactoryBeanName來指定不同的sqlSessionFactory。

config.properties

?
1
2
3
4
5
6
7
8
9
10
11
# 數據庫配置 - Master
master.jdbc.driverClass = com.mysql.jdbc.Driver
master.jdbc.url = jdbc:mysql://192.168.1.11:3306/test
master.jdbc.user = root
master.jdbc.password = jj
 
# - Slave
slave.jdbc.driverClass = com.mysql.jdbc.Driver
slave.jdbc.url = jdbc:mysql://192.168.1.22:3306/test
slave.jdbc.user = root
slave.jdbc.password = jj

使用Mapper

這里是針對主從的情況進行設置的,兩個配置掃描的Mapper是一樣的,所以沒法直接注入,需要通過下面的麻煩方式注入。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Service
public class DemoService {
  private CountryMapper writeMapper;
  private CountryMapper readMapper;
 
  @Resource(name = "sqlSessionMaster")
  public void setWriteMapper(SqlSession sqlSession) {
    this.writeMapper = sqlSession.getMapper(CountryMapper.class);
  }
  @Resource(name = "sqlSessionSlave")
  public void setReadMapper(SqlSession sqlSession) {
    this.readMapper = sqlSession.getMapper(CountryMapper.class);
  }
 
  public int save(Country country){
    return writeMapper.insert(country);
  }
 
  public List<Country> selectPage(int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    return readMapper.select(null);
  }
}

因為sqlSession能通過name區分開,所以這里從sqlSession獲取Mapper。

另外如果需要考慮在同一個事務中寫讀的時候,需要使用相同的writeMapper,這樣在讀的時候,才能獲取事務中的最新數據。

以上是主從的情況。

在分庫的情況時,由于不同Mapper在不同的包下,所以可以直接使用@Resource或者@Autowired注入Mapper,不需要通過sqlSession獲取。

本篇文章,只是一個多數據源的參考,實際應用時,請根據自己的情況進行考慮。

后續,我會利用業余時間,在本文和上面兩個相關鏈接的基礎上,針對MySql多數據源,嘗試開發可以自動切換數據源的插件,因為我對這方面的實際應用不是很熟,所以歡迎大家留言分享自己的解決方案,對這些了解的越多,就越有可能開發出通用的數據源切換插件。

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

原文鏈接:http://blog.csdn.net/isea533/article/details/46815385

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国内精品99 | 草莓香蕉榴莲丝瓜秋葵绿巨人在线看 | 日韩二三区 | 日本三级香港三级久久99 | 亚洲热图| 国产亚洲精品精品国产亚洲综合 | 日韩欧美不卡视频 | 99热这里只有精品一区二区三区 | 亚洲欧美日韩天堂在线观看 | 亚洲福利一区二区精品秒拍 | 糖心vlog视频永久破解版 | 91久久国产露脸精品 | 特黄未满14周岁毛片 | 小舞同人18av黄漫网站 | 女班长的放荡日记高h | 国语在线| re99| 久久免费看少妇高潮A片特爽 | 精品国产自在现线拍400部 | 精品久久成人免费第三区 | 含羞草传媒一天免费看下 | 欧美穿高跟鞋做爰 | 天堂在线观看中文字幕 | 国产一区二区免费不卡在线播放 | hd在线观看免费高清视频 | 动漫美女被羞羞产奶 | 成人au免费视频影院 | www.男人天堂| 白丝校花掀起短裙呻吟小说 | 国产亚洲一欧美一区二区三区 | 国产成人在线综合 | 99久久精品6在线播放 | 亚洲香蕉网久久综合影院3p | 午夜爽喷水无码成人18禁三级 | 日b视频免费 | 免费草比视频 | 无颜之月5集全免费看无删除 | 丁香六月色 | 国产裸露片段精华合集链接 | 日不卡| 武侠艳妇屈辱的张开双腿 |