一個項目裡一般情況下隻會使用到一個資料庫,但有的需求是要顯示其他資料庫的内容,像這樣,我認為有兩種做法
1、在使用另一個資料庫的項目裡寫一些restful接口,滿足移動端PC端的同時也滿足其他應用調用資料的需求;
2、就是在項目裡配置多資料源;
我現在就是要使用另一個資料庫的資料,想到了以上兩種方法,為了更加熟悉spring,我打算使用第二種方案;
我在百度上查了好多關于spring配置多資料源的blog,最後綜合一些,總結一下,用最簡潔,最直覺的方法來實作這個功能
首先,單資料源配置流程如下
一個資料庫對應一個dataSource,然後對應sqlSession,然後再在Dao層實作,配置如下
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${datasource.driver}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="initialSize" value="${datasource.initialSize}"></property>
<property name="maxActive" value="${datasource.maxActive}"></property>
<property name="maxIdle" value="${datasource.maxIdle}"></property>
<property name="minIdle" value="${datasource.minIdle}"></property>
<property name="maxWait" value="${datasource.maxWait}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/iquant/simulated/mapping/*.xml"></property>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.iquant.simulated.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
但資料源就是這樣的配置,資料庫連接配接和一些屬性的配置--->sqlSession配置--->映射檔案哦欸之--->事物管理
如果是多資料源,有下面兩種方案
A和B,先看看B,分别為兩個資料源配置兩個sqlSession,然後再Dao層實作,雖然功能實作了,但是到後期如果在增加多個資料源的話,修改複雜,維護起來也相當的麻煩,也不符合開閉原則;
我們分别配置了兩個 dataSource,兩個sqlSessionFactory,兩個transactionManager,以及關鍵的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName屬性,注入不同的sqlSessionFactory的名稱,這樣的話,就為不同的資料庫對應的 mapper 接口注入了對應的 sqlSessionFactory。
需要注意的是,多個資料庫的這種配置是不支援分布式事務的,也就是同一個事務中,不能操作多個資料庫。這種配置方式的優點是很簡單,但是卻不靈活。
A同樣配置了兩個dataSource,然後實作一個DynamicDataSource類,使用一個sqlSession,這樣維護起來也非常的容易,我是用的就是A,配置起來相當簡單!
毋庸置疑,兩個dataSouce
<bean id="dataSourceSig" class="org.apache.commons.dbcp.BasicDataSource"
<property name="url" value="${datasource.sig.url}" />
<bean id="dataSourceSim" class="org.apache.commons.dbcp.BasicDataSource"
<property name="url" value="${datasource.sim.url}" />
然後配置自己實作的com.iquant.signal.configer.DynamicDataSource類,需指定預設的資料源,如使用其他再進行切換
<bean id="dataSource" class="com.iquant.signal.configer.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceSig" key="dataSourceSig"></entry>
<entry value-ref="dataSourceSim" key="dataSourceSim"></entry>
</map>
</property>
<!-- 預設使用dataSourceSig的資料源 -->
<property name="defaultTargetDataSource" ref="dataSourceSig"></property>
sqlSession和事物和之前一樣,不用改動,實作DynamicDataSource類
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDBType();
}
繼承AbstractRoutingDataSource 重寫determineCurrentLookupKey方法
實作DataSourceContextHolder類
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDBType(String dbType) {
contextHolder.set(dbType);
public static String getDBType() {
return ((String) contextHolder.get());
public static void clearDBType() {
contextHolder.remove();
到此,多資料源就配置完成,如果想切換資料源,在代碼操作對應資料庫之前,加上此句代碼
//注意這裡在調用service前切換到dataSourceSim的資料源
DataSourceContextHolder.setDBType("dataSouceSim");
這樣就完成了多資料源的配置和切換功能,以後還有資料庫添加,在配置一個dataSouce3.4.5.6.等等,就行了
作者: lost blog
關于作者:專注伺服器端開發
本文版權歸作者有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結 如有問題, 可郵件咨詢.