Spring 配置多个数据源,并实现动态切换

2016-11-04 09:50:38来源:oschina作者:miaojiangmin人点击

第七城市

因为最近项目公司需要,需要在mybatis上配置多数据源。多数据源在jpa中配置还是相对简单的,因为个个数据源对应的持久化类相对独立。但是在mybatis上配置还是比较麻烦的。网上找到的教程大多对于目前的项目是需要有比较大的改动的。看到关于不是用spring实现多数据源用到了aop。


参考了这篇文章http://blog.csdn.net/gaofuqi/article/details/46417281。但是这篇文章上缺少一些细节。对于技术比较扎实的人来说,当然没有什么问题。我主要是把缺失的细节补上去。

























































一开始我以为这边配置了默认的datasource,然后程序就会用默认的mysqlDataSource。后来我发现我天真了,系统起不来了,因为我在系统中是配置了事务的。


public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}

定义一个可以设置当前线程的变量的工具类,用于设置对应的数据源名称:


public class DataSourceContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();
/**
* @Description: 设置数据源类型
* @param dataSourceType数据库类型
* @return void
* @throws
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
/**
* @Description: 获取数据源类型
* @param
* @return String
* @throws
*/
public static String getDataSourceType() {
return contextHolder.get();
}
/**
* @Description: 清除数据源类型
* @param
* @return void
* @throws
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}

定义一个aop处理类在数据库事务开启之前切换数据库


public class DataSourceAspect implements MethodBeforeAdvice,AfterReturningAdvice
{
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
DataSourceContextHolder.clearDataSourceType();
}
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
if (method.isAnnotationPresent(DataSource.class))
{
DataSource datasource = method.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSourceType(datasource.name());
}
else
{
DataSourceContextHolder.setDataSourceType(DataSourceConst.MYSQL);
}}
}@Retention(RetentionPolicy.RUNTIME)
@interface DataSource {
String name();
}
public class DataSourceConst {
public static final String MYSQL="mysql";
public static final String ORACLE="oracle";
}



advice-ref="transactionAdvice" order="2" />


这也是我参考的文章中没有补全的。


使用方法的话


查询的话,直接用这个就可以了


DataSourceContextHolder.setDataSourceType(DataSourceConst.ORACLE);

如果涉及到事务的话,在controller层添加注解就ok了


@DataSource(name = DataSourceConst.ORACLE)
第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台