ssm讀寫分離多資料來源
實現讀寫分離的方法
第一種:使用讀寫分離中間外掛,實現讀寫分離,一般大公司會自己開發自己的中介軟體,中小型公司更多的是使用程式實現讀寫分離,中介軟體就不多介紹了。
第二種:就是在程式的讀寫分離,實現AbstractRoutingDataSource類的determineCurrentLookupKey方法
原理:藉助spring的【org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource】這個抽象類實現。
每次去連資料庫的時候,spring會呼叫determineCurrentLookupKey();這個方法去找對應的資料來源。返回值即對應的資料來源
/**
* 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-dao.xml配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 載入資料庫配置檔案和其他配置檔案 -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- 資料庫連線池
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="minIdle" value="20"></property>
</bean> -->
<!-- 資料庫連線池com.alibaba.druid.pool.DruidDataSource -->
<bean id="masterdataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="maxActive" value="100"></property>
<property name="minIdle" value="20"></property>
</bean>
<!-- 讀庫 -->
<bean id="slavedataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.r.url}"></property>
<property name="username" value="${jdbc.r.username}"></property>
<property name="password" value="${jdbc.r.password}"></property>
<property name="driverClassName" value="${jdbc.r.driver}"></property>
<property name="maxActive" value="100"></property>
<property name="minIdle" value="20"></property>
</bean>
<!-- 動態資料來源 -->
<bean id="dynamicDataSource" class="com.tongzuwang.datasource.DynamicDataSource">
<!-- 通過key-value關聯資料來源 -->
<property name="targetDataSources">
<map>
<entry value-ref="masterdataSource" key="masterdataSource"></entry>
<entry value-ref="slavedataSource" key="slavedataSource"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="masterdataSource" />
</bean>
<!-- 整合mybatis: SqlsessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 資料來源 -->
<property name="dataSource" ref="dynamicDataSource"></property>
<!-- mybatis配置檔案 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
</bean>
<!-- 注入DAO物件:配置mapper MapperFactoryBean:用於生成mapper代理物件 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置掃描包的路徑,如果要掃描多個包,中間使用逗號隔開 -->
<property name="basePackage" value="com.tongzuwang.able"></property>
<!-- 使用sqlSessionFactoryBeanName -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
</beans>
第二步,先繼承AbstractRoutingDataSource 類實現determineCurrentLookupKey方法。
package com.tongzuwang.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
*
* override determineCurrentLookupKey
* Title: determineCurrentLookupKey
* Description: 自動查詢datasource
*
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.getDbType();
}
}
這個方法要返回的值。那麼如何設定,讓這個方法的返回值是根據我們的需要返回dataSource由於這個方法沒有入參,並且是spring自動呼叫的,因此考慮使用靜態變數儲存dataSource的key,在呼叫sql語句前設定靜態變數的值,然後在這個方法中得到靜態變數的值,返回。又考慮到多執行緒,同時可能會有很多請求,為避免執行緒之間相互干擾,考慮使用threadLocal。
先看儲存dataSourceKey的容器類
package com.tongzuwang.datasource;
public class DBContextHolder {
/**
* 執行緒threadlocal
*/
private static ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static String master = "masterdataSource";
public static String slave = "slavedataSource";
public static String getDbType() {
String db = contextHolder.get();
if (db == null) {
db = master;// 預設是讀寫庫
}
return db;
}
/**
*
* 設定本執行緒的dbtype
*
* @param str
* @see [相關類/方法](可選)
* @since [產品/模組版本](可選)
*/
public static void setDbType(String str) {
contextHolder.set(str);
}
/**
* clearDBType
*
* @Title: clearDBType
* @Description: 清理連線型別
*/
public static void clearDBType() {
contextHolder.remove();
}
}
第三部,在訪問資料之前使用DBContextHolder的靜態方法,設定資料來源,預設是主庫
DBContextHolder .setDbType(DBContextHolder .master);//設定資料來源為主庫
這是,我在CSDN的第一篇文章,水平比較低,大家見諒!
相關文章
- Spring Boot MyBatis 動態資料來源切換、多資料來源,讀寫分離Spring BootMyBatis
- Spring Boot + Mybatis 多資料來源配置實現讀寫分離Spring BootMyBatis
- springboot多資料來源配合docker部署mysql主從實現讀寫分離Spring BootDockerMySql
- 資料庫讀寫分離資料庫
- 資料讀寫壓力大,讀寫分離
- 資料庫的讀寫分離資料庫
- Spring動態資料來源+Mybatis攔截器實現資料庫讀寫分離SpringMyBatis資料庫
- 大資料資料庫讀寫分離分庫分表大資料資料庫
- 讀寫分離的的資料同步?
- 資料庫讀寫分離Master-Slave資料庫AST
- MySQL 中讀寫分離資料延遲MySql
- Discuz!NT資料庫讀寫分離方案資料庫
- Spring-Boot 多資料來源配置+動態資料來源切換+多資料來源事物配置實現主從資料庫儲存分離Springboot資料庫
- 資料庫治理利器:動態讀寫分離資料庫
- RDS讀寫分離,海量資料一鍵搞定
- Spring實現資料庫讀寫分離Spring資料庫
- golang saas框架,資料庫級別隔離、讀寫分離Golang框架資料庫
- Spring Aop實現資料庫讀寫分離Spring資料庫
- SpringCloud微服務實戰——搭建企業級開發框架(二十七):整合多資料來源+Seata分散式事務+讀寫分離+分庫分表SpringGCCloud微服務框架分散式
- SSM(八)動態切換資料來源SSM
- Redis的讀寫分離Redis
- Laravel讀寫分離原理Laravel
- MySQL Amoeba讀寫分離MySql
- Amoeba for mysql讀寫分離MySql
- MySQL讀寫分離AtlasMySql
- mongodb的讀寫分離MongoDB
- 資料庫的讀寫分離與負載均衡策略資料庫負載
- 資料庫讀寫分離,主從同步實現方法資料庫主從同步
- shardingjdbc + jpa 完成讀寫分離配置及資料分片JDBC
- 【資料庫訪問優化方案之讀寫分離】資料庫優化
- OneProxy5.8.1資料庫讀寫分離特性試驗資料庫
- Discuz!NT3.1 資料庫讀寫分離 程式碼資料庫
- 通過STANDBY資料庫實現讀寫分離時索引過多的問題資料庫索引
- MyCat分庫分表、讀寫分離
- Mycat 讀寫分離+分庫分表
- 淺談高效能資料庫叢集——讀寫分離資料庫
- 使用Spring AOP切面解決資料庫讀寫分離Spring資料庫
- 資料庫 讀寫分離 為什麼提高效能資料庫