從此抄錄:https://blog.csdn.net/ll535299/article/details/78203634
1、先配置兩個數據源,附上主要代碼,給自己回憶,詳解見開頭鏈接
<!-- 配置數據源 --> <bean id="szDS" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${szds.dbhost}"/><property name="username" value="${szds.dbusername}"/><property name="password" value="${szds.dbpwd}"/><property name="initialSize" value="1"/><property name="minIdle" value="1"/><property name="maxActive" value="30"/><property name="maxWait" value="${szds.maxWait}"/><property name="timeBetweenEvictionRunsMillis" value="${szds.timeBetweenEvictionRunsMillis}"/><property name="minEvictableIdleTimeMillis" value="${szds.minEvictableIdleTimeMillis}"/><property name="validationQuery" value="SELECT 'j'"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="poolPreparedStatements" value="false"/><property name="filters" value="${szds_common.filters}"/><property name="connectionProperties" value="${szds_common.connectionProperties}"/> </bean> <!-- 配置上報系統數據源 --> <bean id="tntDS" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${szds_tnt.dbhost}"/><property name="username" value="${szds_tnt.dbusername}"/><property name="password" value="${szds_tnt.dbpwd}"/><property name="initialSize" value="1"/><property name="minIdle" value="1"/><property name="maxActive" value="30"/><property name="maxWait" value="${szds_tnt.maxWait}"/><property name="timeBetweenEvictionRunsMillis" value="${szds_tnt.timeBetweenEvictionRunsMillis}"/><property name="minEvictableIdleTimeMillis" value="${szds_tnt.minEvictableIdleTimeMillis}"/><property name="validationQuery" value="SELECT 'j'"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="poolPreparedStatements" value="false"/><property name="filters" value="${szds_common.filters}"/><property name="connectionProperties" value="${szds_common.connectionProperties}"/> </bean>
2、自定義一個數據源類,該類繼承 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource并重寫determineCurrentLookupKey()方法
public class RoutingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceHolder.getDataSourceType();}}
3、將該類交由sping管理,其在spring配置文件中配置如下
<bean id="dataSource" class="com.wayyue.sz.asgard.admin.dataSource.RoutingDataSource"><!-- 為targetDataSources注入兩個數據源 --><property name="targetDataSources"><map key-type="java.lang.String"><entry key="szDS" value-ref="szDS"/><entry key="tntDS" value-ref="tntDS"/></map></property><!-- 為指定數據源RoutingDataSource注入默認的數據源--><property name="defaultTargetDataSource" ref="szDS"/> </bean>
4、事務配置如下
<!-- 開啟aop注解--> <aop:aspectj-autoproxy proxy-target-class="true"/><!-- mybatis 配置--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="mapperLocations" value="classpath:sqlmap/*.xml"/> </bean><bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.wayue.sz.biz.orm.mapper"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean><!-- 配置事物管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/> </bean><!-- 開啟注解控制事物--> <tx:annotation-driven transaction-manager="transactionManager"/>
5、編寫一個數據源持有類DataSourceHolder
package com.wayyue.sz.asgard.admin.dataSource;public class DataSourceHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();/*** 設置數據源類型** @param dataSourceType 數據庫類型*/public static void setDataSourceType(String dataSourceType) {contextHolder.set(dataSourceType);}/*** 獲取數據源類型** @return*/public static String getDataSourceType() {return contextHolder.get();}/*** 清除數據源類型*/public static void clearDataSourceType() {contextHolder.remove();}}
6.自定義注解
package com.wayyue.sz.asgard.admin.aspect;import java.lang.annotation.*;/*** 數據源** @author xxx* @date 2018年11月19日21:05:13*/ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface DataSource {String value() default "";}
7、動態切換數據源
package com.wayyue.sz.asgard.admin.aspect;import com.wayyue.sz.asgard.admin.dataSource.DataSourceHolder; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Repository;import java.lang.reflect.Method;@Aspect @Repository public class DataSourceAspect {@Pointcut("execution(* com.wayyue.sz.asgard.admin.service.tnt..*.*(..))")private void anyMethod() {}@AfterReturning(value = "anyMethod()", returning = "result")public void afterReturning(JoinPoint joinPoint, Object result) {DataSourceHolder.clearDataSourceType();}@Before(value = "anyMethod()")public void before(JoinPoint joinPoint) throws Throwable {MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();Method method = methodSignature.getMethod();//如果方法體上使用了DataSource注解if (method.isAnnotationPresent(DataSource.class)) {//獲取該方法上的注解名DataSource datasource = method.getAnnotation(DataSource.class);//將方法體上的注解的值賦予給DataSourceHolder數據源持有類 DataSourceHolder.setDataSourceType(datasource.value());}}}
8、若方法體上沒有注解,則都是使用默認數據源,如果有以下注解,則使用指定的數據源
@Override @DataSource("tntDS") public String getDeal() { // 新數據源 String s = tntDealInfoMapper.dockingOrderCode();return s; }@Override public String getCode() { // 默認數據源return tntDealInfoMapper.getCode(); }
?