一、jdbc.properties文件
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc1.url=jdbc\:oracle\:thin\:@xxx.xxx.xxx.xxx\:1521\:xxx
jdbc1.username=xxx
jdbc1.password=xxx
jdbc2.url=jdbc\:oracle\:thin\:@xxx.xxx.xxx.xxx\:1521\:xxx
jdbc2.username=xxx
jdbc2.password=xxx
validationQuery=select 1 from dual
二、Spring-mybatis.xml文件
<!-- 引入配置文件 -->
<context:property-placeholder location="classpath:properties/*.properties" ignore-unresolvable="true" />
<!-- 数据源1 -->
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc1.url}" />
<property name="username" value="${jdbc1.username}" />
<property name="password" value="${jdbc1.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="initialSize" value="0" />
<property name="maxActive" value="20" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="0" />
<property name="maxWait" value="60000" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="25200000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="1800" />
<property name="logAbandoned" value="true" />
<property name="filters" value="mergeStat" />
</bean>
<!--数据源2-->
<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc2.url}" />
<property name="username" value="${jdbc2.username}" />
<property name="password" value="${jdbc2.password}" />
<property name="initialSize" value="0" />
<property name="maxActive" value="20" />
<property name="maxIdle" value="20" />
<property name="minIdle" value="0" />
<property name="maxWait" value="60000" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="25200000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="1800" />
<property name="logAbandoned" value="true" />
<property name="filters" value="mergeStat" />
</bean>
<!-- 自定义数据源切换类 -->
<bean id="dynamicDataSource" class="gateway.common.DynamicDataSource">
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource2" />
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource1" value-ref="dataSource1"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
</map>
</property>
</bean>
<!-- MyBatis SqlSessionFactoryBean 配置 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<property name="configLocation" value="classpath:xml/mybatis-config.xml" />
<property name="typeAliasesPackage" value="gateway.entity" />
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml" />
</bean>
<!-- 扫描dao -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="gateway.dao" />
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dynamicDataSource" />
</bean>
<!-- 映射接口 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.baimi.routerweb.mapper"></property>
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 -->
<aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* gateway.service.impl.*.*(..))" /> </aop:config>
三、自定义数据源选择器类
package gateway.common;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();
public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
四、自定义注解
package gateway.common;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义DataSource的注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface DataSwitch {
String dataSource() default "";
}
五、前置通知(我这里切的是controller,切哪自定义,改一下包名就OK)
@Aspect
public class LogAopAction {
//配置接入点
@Pointcut("execution(* gateway.web.controller..*.*(..))")
private void controllerAspect(){}//定义一个切入点
@Before("controllerAspect()")
public void dataSwitch(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature =(MethodSignature) signature;
Method method = methodSignature.getMethod();
DataSwitch data = null;
String dataSource = "";
if(method != null){
data = method.getAnnotation(DataSwitch.class);
if(data != null){
dataSource = data.dataSource();
if(dataSource != null){
DynamicDataSource.setDataSourceKey(dataSource);
}
}
}
}
}
六、Spring-mvc中添加aop配置
<!-- 开启aop,对类代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="logAopAction" class="com.datacvg.zx.aspectj.LogAopAction"/>
七、在需要切换数据源的controller方法上添加自定义注解
@DataSwitch(dataSource="dataSource1")