Spring實現資料庫讀寫分離
資料庫讀寫分離是最基本的DB擴充套件方式,我們可以在應用中自己實現,決定什麼業務訪問寫庫,什麼業務訪問讀庫。
Spring提供了一套機制可以宣告式地實現讀寫分離,簡化我們的開發。下面把最主要的幾塊列出來。
1,AbstractRoutingDataSource,這是Spring提供的最核心的元件,由它來管理所有的寫庫、讀庫,並統一對外提供dataSource。
在這裡,DynamicDataSource繼承了AbstractRoutingDataSource,並在配置中指明瞭所有的讀寫庫。dynamicDs_galaxy就是統一對外提供的dataSource,
之後,注入DAO、transaction管理,都將使用dynamicDs_galaxy。
在程式碼裡實現determineCurrentLookupKey方法,該方法就一個作用:獲取key,以便根據key獲取哪個datasource。
2,DynamicDataSourceInterceptor,這是個攔截器,最終會以advice的形式攔截所有需要訪問DB的業務,它的作用是給需要DB訪問的業務分配一個key,
這個key用來determineCurrentLookupKey,最終確定訪問哪個dataSource。
程式碼:根據業務方法名來分配key。
DynamicDataSourceKeyHolder裡面持有ThreadLocal,是執行緒安全的。
Spring提供了一套機制可以宣告式地實現讀寫分離,簡化我們的開發。下面把最主要的幾塊列出來。
1,AbstractRoutingDataSource,這是Spring提供的最核心的元件,由它來管理所有的寫庫、讀庫,並統一對外提供dataSource。
在這裡,DynamicDataSource繼承了AbstractRoutingDataSource,並在配置中指明瞭所有的讀寫庫。dynamicDs_galaxy就是統一對外提供的dataSource,
之後,注入DAO、transaction管理,都將使用dynamicDs_galaxy。
點選(此處)摺疊或開啟
-
<bean id="dynamicDs_galaxy" class="com.sogou.earth.api.common.db.DynamicDataSource">
-
<property name="targetDataSources">
-
<map key-type="java.lang.String">
-
<entry key="master" value-ref="ds_galaxy_master" />
-
<entry key="slave" value-ref="ds_galaxy_slave" />
-
</map>
-
</property>
-
<property name="defaultTargetDataSource" ref="ds_galaxy_master" />
- </bean>
在程式碼裡實現determineCurrentLookupKey方法,該方法就一個作用:獲取key,以便根據key獲取哪個datasource。
點選(此處)摺疊或開啟
-
package com.sogou.earth.api.common.db;
-
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-
-
public final class DynamicDataSource extends AbstractRoutingDataSource {
-
-
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
-
-
protected Object determineCurrentLookupKey() {
-
Object object = DynamicDataSourceKeyHolder.getDataSourceKey();
-
logger.debug("determineCurrentLookupKey:" + object);
-
return object;
-
}
- }
2,DynamicDataSourceInterceptor,這是個攔截器,最終會以advice的形式攔截所有需要訪問DB的業務,它的作用是給需要DB訪問的業務分配一個key,
這個key用來determineCurrentLookupKey,最終確定訪問哪個dataSource。
點選(此處)摺疊或開啟
-
<bean id="dynamicDsInterceptor_galaxy" class="com.sogou.earth.api.common.db.DynamicDataSourceInterceptor">
-
<property name="attributeSource">
-
<list>
-
<value>query*,slave</value>
-
<value>count*,slave</value>
-
<value>find*,slave</value>
-
<value>get*,slave</value>
-
<value>list*,slave</value>
-
<value>*,master</value>
-
</list>
-
</property>
- </bean>
程式碼:根據業務方法名來分配key。
點選(此處)摺疊或開啟
-
package com.sogou.earth.api.common.db;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import org.aopalliance.intercept.MethodInterceptor;
-
import org.aopalliance.intercept.MethodInvocation;
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
import org.springframework.util.PatternMatchUtils;
-
-
/**
-
* 設定資料來源KEY的攔截器
-
*
-
*/
-
public class DynamicDataSourceInterceptor implements MethodInterceptor {
-
-
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceInterceptor.class);
-
/**
-
* 方法和使用資料來源key的對應關係
-
*/
-
private List<String> attributeSource = new ArrayList<String>();
-
-
public Object invoke(MethodInvocation invocation) throws Throwable {
-
final String methodName = invocation.getMethod().getName();
-
String key = null;
-
for (String value : attributeSource) {
-
String mappedName = value.split(\",\")[0];
-
if (isMatch(methodName, mappedName)) {
-
key = value.split(\",\")[1];
-
break;
-
}
-
}
-
logger.debug(\"methodName:\" + methodName);
-
if (null != key) {
-
DynamicDataSourceKeyHolder.setKey(key);
-
}
-
-
return invocation.proceed();
-
}
-
-
private boolean isMatch(String methodName, String mappedName) {
-
return PatternMatchUtils.simpleMatch(mappedName, methodName);
-
}
-
-
public List<String> getAttributeSource() {
-
return attributeSource;
-
}
-
-
public void setAttributeSource(List<String> attributeSource) {
-
this.attributeSource = attributeSource;
-
}
-
- }
DynamicDataSourceKeyHolder裡面持有ThreadLocal,是執行緒安全的。
點選(此處)摺疊或開啟
-
package com.sogou.earth.api.common.db;
-
-
import org.slf4j.Logger;
-
import org.slf4j.LoggerFactory;
-
-
public class DynamicDataSourceKeyHolder {
-
-
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceKeyHolder.class);
-
-
private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<String>();
-
-
public static void setKey(String key) {
-
dataSourceHolder.set(key);
-
}
-
-
public static String getDataSourceKey() {
-
return (String) dataSourceHolder.get();
-
}
- }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28912557/viewspace-1577667/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring Aop實現資料庫讀寫分離Spring資料庫
- 資料庫讀寫分離資料庫
- 資料庫讀寫分離,主從同步實現方法資料庫主從同步
- 大資料資料庫讀寫分離分庫分表大資料資料庫
- Spring Boot + Mybatis 多資料來源配置實現讀寫分離Spring BootMyBatis
- ShardingSphere(七) 讀寫分離配置,實現分庫讀寫操作
- (7)資料庫讀寫分離,主從同步實現方法(資料庫設定)資料庫主從同步
- 資料庫中介軟體sharding-jdbc實現讀寫分離資料庫JDBC
- Docker實現Mariadb分庫分表、讀寫分離Docker
- 資料庫讀寫分離Master-Slave資料庫AST
- 直播賣貨系統,如何實現mysql資料庫的讀寫分離MySql資料庫
- MySQL-SpringBoot整合JPA實現資料讀寫分離MySqlSpring Boot
- 資料庫治理利器:動態讀寫分離資料庫
- ShardingSphere + Mysql,實現分庫分表、讀寫分離,並整合 SpringBootMySqlSpring Boot
- 使用Spring實現訪問主從資料庫的讀寫和只讀事務/事物的分離路由 -Vlad MihalceaSpring資料庫路由
- ProxySQL實現MySQL讀寫分離MySql
- golang saas框架,資料庫級別隔離、讀寫分離Golang框架資料庫
- 分庫分表(6)--- SpringBoot+ShardingSphere實現分表+ 讀寫分離Spring Boot
- Java程式設計師乾貨學習筆記—Spring結合MyBatis實現資料庫讀寫分離Java程式設計師筆記SpringMyBatis資料庫
- 資料讀寫壓力大,讀寫分離
- 【Mongo】Mongo讀寫分離的實現Go
- 做資料庫分離讀寫時,sqlServer資料庫資料同步的問題:資料庫SQLServer
- MyCat分庫分表、讀寫分離
- 資料庫的讀寫分離與負載均衡策略資料庫負載
- Sharding-JDBC基本使用,整合Springboot實現分庫分表,讀寫分離JDBCSpring Boot
- PostgreSQL+Pgpool實現HA讀寫分離SQL
- docker+atlas+mysql實現讀寫分離DockerMySql
- Kubernetes 中實現 MySQL 的讀寫分離MySql
- 淺談高效能資料庫叢集——讀寫分離資料庫
- 讀寫分離 & 分庫分表 & 深度分頁
- 位元組面試:什麼是讀寫分離?讀寫分離的底層如何實現?面試
- ssm讀寫分離多資料來源SSM
- MySQL 中讀寫分離資料延遲MySql
- ProxySQL實現Mysql讀寫分離 - 部署手冊MySql
- SpringBoot 專案優雅實現讀寫分離Spring Boot
- 搭建MySQL主從實現Django讀寫分離MySqlDjango
- MHA+ProxySQL實現讀寫分離高可用SQL
- 深度:微服務化的資料庫設計與讀寫分離微服務資料庫
- 搭建基於springmvc,ibatis的工程實現讀寫分離,配置分離SpringMVCBAT