先说思路及过程.
之前写过一篇JPA 多数据源的, 那个去年第一次接触. 也是弄了好久.
最近做一个项目需要jdbc 和 mybatis的整合. 数据源有6个. 如果按照配置多个sessionFactory来弄不太雅观.
正好看到百度发现,项目中本身是有集成多数据源切换的实现的, 只是没人注意和不会使用.
好了下面来说正题.
第一. 多数据源的整理,这个按照自己公司需求配置就好. 这个容易.
只是在dataSource 中指向了DynamicDataSouce类. 这是动态数据切换的核心.
.
DynamicDataSource 类的代码如下. 具体原理可百度看其他的文章. 本方法在一般项目中只需要第一个方法就可满足
. 本类中引入DataSourceContextHolder类实现当前应用中, 使用线程的方式来进行数据源切换.如下
import java.util.Map;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
/**
*
* @ClassName: DynamicDataSource
* @Description: TODO(动态获取数据源 关联app-config)
* @author ranxing
* @date 2018年5月3日 上午10:41:43
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
/*
* 该方法必须要重写 方法是为了根据数据库标示符取得当前的数据库
*/
@Override
public Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceName();
}
@Override
public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
super.setDataSourceLookup(dataSourceLookup);
}
@Override
public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void setTargetDataSources(Map targetDataSources) {
super.setTargetDataSources(targetDataSources);
//重点
super.afterPropertiesSet();
}
}
--------------------------
/**
*
* @ClassName: DataSourceContextHolder
* @Description: TODO(通过 TheadLocal 来保存每个线程选择哪个数据源的标志(key):)
* @author ranxing
* @date 2018年5月3日 上午10:39:38
*
*/
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder=new ThreadLocal<String>();
public static void setDataSourceType(String dataSourceName){
contextHolder.set(dataSourceName);
}
public static String getDataSourceName(){
return (String) contextHolder.get();
}
public static void clearDataSourceType(){
contextHolder.remove();
}
}
---------------------
OK 如上的配置后, 在你原来的项目中, 只要是单一数据源可以正常使用的情况下.在操作数据库之前调用
DataSourceContextHolder.setDataSourceType("dataSource1");//dataSource1
方法, 即可切换到指定的数据源. 这里的参数是 dataSouce中的key 值. 本人已在jdbc mybatis jpa 的配置中均可正常调用.
附一个jpa基本的测试类
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version> 3.2.4.RELEASE </version>
<scope>provided</scope>
</dependency>
import java.util.List;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.com.taiji.repository.CodeRepository;
import cn.com.taiji.util.DataSourceContextHolder;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/*-config.xml" })
public class ApplicationTests {
@Inject
CodeRepository codeRepository;
@Test
public void runsss() {
DataSourceContextHolder.setDataSourceType("dataSource1");//dataSource1
List<?> list2 = codeRepository.findAllCodes();
DataSourceContextHolder.setDataSourceType("centerdb");//dataSource1
List<?> list = codeRepository.findAllCodes();
System.out.println(list.size() +"__" + list2.size());
}
}