spring+myBatis 配置多數據源,切換數據源



注:本文來源於  tianzhiwuqisspring+myBatis 配置多數據源,切換數據源


      一個項目里一般情況下只會使用到一個數據庫,但有的需求是要顯示其他數據庫的內容,像這樣,我認為有兩種做法

1、在使用另一個數據庫的項目里寫一些restful接口,滿足移動端PC端的同時也滿足其他應用調用數據的需求;

2、就是在項目里配置多數據源;

       我現在就是要使用另一個數據庫的數據,想到了以上兩種方法,為了更加熟悉spring,我打算使用第二種方案;我在百度上查了好多關於spring配置多數據源的blog,最后綜合一些,總結一下,用最簡潔,最直觀的方法來實現這個功能.

首先,單數據源配置流程如下

image


一個數據庫對應一個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>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.iquant.simulated.dao" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>



但數據源就是這樣的配置,數據庫連接和一些屬性的配置--->sqlSession配置--->映射文件哦欸之--->事物管理

如果是多數據源,有下面兩種方案


A和B,先看看B,分別為兩個數據源配置兩個sqlSession,然后再Dao層實現,雖然功能實現了,但是到后期如果在增加多個數據源的話,修改復雜,維護起來也相當的麻煩,也不符合開閉原則;

A同樣配置了兩個dataSource,然后實現一個DynamicDataSource類,使用一個sqlSession,這樣維護起來也非常的容易,我是用的就是A,配置起來相當簡單!

毋庸置疑,兩個dataSouce


<bean id="dataSourceSig" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${datasource.driver}" />
    <property name="url" value="${datasource.sig.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="dataSourceSim" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="${datasource.driver}" />
    <property name="url" value="${datasource.sim.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>


然后配置自己實現的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>
</bean>
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的數據源    
// 經過測試可以寫到serice層
DataSourceContextHolder.setDBType("dataSouceSim");
// 若要切換其他數據源,可能要想進行cleanDBType操作  
DataSourceContextHolder.cleanDBType();
// 然后再對其他數據源進行setDBType

這樣就完成了多數據源的配置和切換功能,以后還有數據庫添加,在配置一個dataSouce3.4.5.6.等等,就行了

參考BLOG

http://blog.csdn.net/wangpeng047/article/details/8866239

http://x125858805.iteye.com/blog/2061713


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM