Spring4 + jpa 或者 Mybaits 或者JDBC 動態資料庫切換例項 (1)
先說思路及過程.
之前寫過一篇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());
}
}