从此抄录: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(); }