jar包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
配置数据源(用阿里的druid管理数据源)
<bean id="db1" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
</bean>
<bean id="dataSource" class="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="db1" value-ref="db1"/>
<entry key="db2" value-ref="db2"/>//db2跟上面db1一样配置
</map>
</property>
<!--默认数据源-->
<property name="defaultTargetDataSource" ref="db1"/>
</bean>
配置session
<bean id="sqlSessionFactory"
class="cn.zj.pubinfo.comm.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.zjpii.wanbao.entity" />
<property name="typeAliasesSuperType" value="cn.zj.pubinfo.comm.core.entity.BaseEntity" />
<property name="mapperLocations" value="classpath*:/mappings/**/*.xml" />
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
这里是配置了分页的插件,没用到不用配
<property name="plugins">
<array>
<!-- 分页 -->
<bean class="com.github.pagehelper.PageHelper">
<property name="properties" >
<value>
dialect=oracle
offsetAsPageNum=true
rowBoundsWithCount=true
pageSizeZero=truereasonable=false
reasonable=true
<!-- params=pageNum=pageHelperStart;pageSize=pageHelperRows; -->
supportMethodsArguments=false
</value>
</property>
</bean>
</array>
</property>
</bean>
配置事务
<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 -->
<context:component-scan base-package="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb,com.zjpii.wanbao.service.impl,cn.zj.pubinfo.comm.mybatis.spring.aspect"><!-- base-package
如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 定义事务 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
实现AbstractRoutingDataSource类 作为数据源
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String dbKey=DataSourceHolder.getDataSources();
return dbKey;
}
}
用ThreadLcoal管理当前数据源
public class DataSourceHolder {
private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();
public static void setDataSources(String dataSource) {
dataSources.set(dataSource);
}
public static String getDataSources() {
return dataSources.get();
}
}
AOP支持
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 动态切换数据源切面
*/
@Component
@Aspect
@Order(-1)
public class DynamicDataSourceInterceptor {
@Around(value = "@annotation(switchDB)")
public Object process(ProceedingJoinPoint point, SwitchDB switchDB) throws Throwable {
Object returnValue;
try {
DataSourceHolder.setDataSources(switchDB.dbID());
returnValue = point.proceed(point.getArgs());
} finally {
DataSourceHolder.setDataSources(null);
}
return returnValue;
}
}
注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 动态切换数据源
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SwitchDB {
String dbID();
}
在spring里面扫描
<aop:aspectj-autoproxy proxy-target-class="true" />
<context:component-scan base-package="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb"><!-- base-package
如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
在service层方法中添加注解
@SwitchDB(dbID = "db1")
public List<String> find() {
return userDao.find();
}
db1已经在数据源配置中配置
现在即可以切换数据源进行操作了。