多資料源配置:實作主(Master)從(Slave)庫分離方式,減輕主庫壓力,從庫負責查詢。還有使用中需要用到兩個資料庫時候,使用多資料源配置,可以實作多庫之間切換。
applicationContext.xml
<!-- 配置資料源 Master主-->
<bean id="dataSourceMaster" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"></property>
<property name="url" value="資料庫位址"></property>
<property name="username" value="賬戶名"></property>
<property name="password" value="密碼"></property>
<property name="maxActive" value="20"/>
<property name="maxIdle" value="30"/>
<property name="initialSize" value="1"/>
<property name="maxWait" value="10000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="logAbandoned" value="true"/>
</bean>
<!-- 配置資料源 Slave從庫-->
<bean id="dataSourceSlave" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"></property>
<property name="url" value="資料庫位址"></property>
<property name="username" value="帳号"></property>
<property name="password" value="密碼"></property>
<property name="maxActive" value="20"/>
<property name="maxIdle" value="30"/>
<property name="initialSize" value="1"/>
<property name="maxWait" value="10000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="logAbandoned" value="true"/>
</bean>
<!-- 資料源 切換 -->
<bean id="multipledataSource" class="com.xxx.mobile.datasource.MultipleDataSource"><!-- 注入資料源路由 -->
<property name="defaultTargetDataSource" ref="dataSourceMaster"/><!-- 預設資料源 -->
<property name="targetDataSources">
<map key-type="java.lang.String"><!-- 把主從資料庫添加到map集合 -->
<entry key="master" value-ref="dataSourceMaster"/>
<entry key="slave" value-ref="dataSourceSlave"/>
</map>
</property>
</bean>
<!-- Aop 資料源 切換 -->
<bean id="dataSourceSwitchingAop" class="com.xxx.mobile.datasource.MultipleDataSourceAspectAdvice"/>
<!-- 配置aop -->
<aop:config>
<!-- 切換資料源的事務需要放到資料庫事務開啟前執行。針對上述代碼示例中,配置aop時需要指定order(值越小,執行越靠前) -->
<aop:aspect id="dataSourceSwitching" ref="dataSourceSwitchingAop" order="0"><!-- 注入資料源路由 dataSourceSwitchingAop-->
<aop:pointcut id="dataSourceSwitchingService"
expression="execution(* com.xxx.mobile.mapper.*.*(..))"/>
<aop:before method="switchDataSource" pointcut-ref="dataSourceSwitchingService"/>
</aop:aspect>
</aop:config>
<!-- 配置Session工廠 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipledataSource"></property><!-- 注入 資料源切換 id multipledataSource-->
<!-- 加載mybatis.cfg.xml檔案 -->
<property name="configLocation" value="classpath:mybatis.cfg.xml"></property>
<!-- 自動掃描需要定義類别名的包,将包内的JAVA類的類名作為類别名 -->
<property name="typeAliasesPackage" value="com.infolink.trade.beans"></property>
</bean>
MultipleDataSource.java
/**
* 多資料源配置
* AbstractRoutingDataSource 資料源路由
* 實作其抽象方法determineCurrentLookupKey(),進而實作對不同資料源的路由功能
*/
public class MultipleDataSource extends AbstractRoutingDataSource{
//ThreadLocal 保證每個請求都會由一個線程來處理, 是分層系統中共享變量的 進階方式
private final static ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();
public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
MultipleDataSourceAspectAdvice.java
/**
* AOP
* 資料源 轉換
*/
@Component //自動掃描
public class MultipleDataSourceAspectAdvice {
public void switchDataSource(JoinPoint joinPoint){
Object object = joinPoint.getTarget();
DataSourceKey annotation = AnnotationUtils.findAnnotation(object.getClass(),DataSourceKey.class);
if(null!=annotation){//沒有注解的用預設值
String value = annotation.value();
if(null!=value&&value.length()>0){
MultipleDataSource.setDataSourceKey(value);
}
}else{
MultipleDataSource.setDataSourceKey("master");
}
}
}
注:配置檔案需要配置掃描 和 啟動AOP支援
DataSourceKey.java
/**
* 自定義注解
* 在mapper包下類或方法上添加自定義注解@DataSourceKey(value="slave")
* 進而實作切換資料源到 slave
*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceKey {
String value() default "slave";
}
使用時候隻需要在對應類或方法上添加注解,即可實作資料源切換
例:
@MapperScan
@DataSourceKey(value="slave") //切換資料源
public interface CardDao {}//類名
注::從庫可以多個,主庫預設一個
本文為部落客第一次發文,學習使用過程中整理了一下,歡迎大神們多多提建議、讨論。