mybatis+springmvc 多數據源切換

題外話:有n個小系統,如今須要用一個系統監控這n個系統中的數據。解決方案能夠是把n個小系統中的數據都同步到一個大的數據庫中,然而,這個並非最佳解決辦法。java

      我如今碰到一個問題,就是相似這樣。每一個小系統的數據表,字段、字段類型徹底同樣,實體類也是同樣的,因而,我就想到用mybatis的多數據源切換來解決,因爲這種用法並不常見。能在網上找的資料甚少,因而,查找API、源碼,終於功夫不負有心人,找到了一種比較穩定的解決辦法,寫文以記之。spring

 

一、首先須要寫出這n個數據源的配置,(這裏以阿里巴巴的數據庫鏈接池爲例,dbcp的鏈接池我試過也是能夠的)數據庫

<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> 
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        
        <property name="maxActive" value="${dbcp.maxActive}" />
        <property name="maxIdle" value="${dbcp.maxIdle}" />
        
        <property name="filters" value="stat,log4j" />  
        <property name="proxyFilters">
            <list>
                 <ref bean="stat-filter" />
                 <ref bean="log-filter" />
            </list>
        </property>
                
        <property name="removeAbandoned" value="true"></property>
        <property name="removeAbandonedTimeout" value="${dbcp.removeAbandoned}"></property>
        <property name="connectionProperties"><value>clientEncoding=UTF8</value></property>
        
        <property name="testWhileIdle"><value>true</value></property>
        <property name="testOnBorrow"><value>false</value></property>
        <property name="testOnReturn"><value>false</value></property>
        <property name="validationQuery"><value>select sysdate from dual</value></property>
        <property name="validationQueryTimeout"><value>1</value></property>
        <property name="timeBetweenEvictionRunsMillis"><value>30000</value></property>
        <property name="numTestsPerEvictionRun"><value>20</value></property>
    </bean>

如此重複的配置n個不一樣的數據源,以供切換。mybatis

二、數據源配置ui

<bean id="dataSource" class="com.xxx.common.spring.RoutingDataSourceSupport"> 
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="dataSource1" value-ref="dataSource1"/><!-- 如此重複的配置n個須要切換的數據源 -->
                ...
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSource1"></property><!-- 設置默認的數據源 -->
    </bean>

三、RoutingDataSourceSupport方法url

package com.xxx.common.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class RoutingDataSourceSupport extends AbstractRoutingDataSource {
    /** 日誌句柄 */
    private static Logger logger = LoggerFactory.getLogger(RoutingDataSourceSupport.class);
    private final static ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();

    /**
     * @param key
     *         設置當前的數據源
     */
    public static void setDataSource(String key) {
        dataSourceKey.set(key);
    }


    /**
     * 恢復默認的數據源
     */
    public static void clearDataSource() {
        dataSourceKey.set(null);
    }
    
    protected Object determineCurrentLookupKey() {
        String key = dataSourceKey.get();
        logger.info("當前數據源:"+key);
        return key;
    }
}

四、如何使用?spa

RoutingDataSourceSupport.setDataSource(dataSource);
// 須要執行數據源切換的位置
do something....
RoutingDataSourceSupport.clearDataSource();

 

後記,也能夠不使用日誌

RoutingDataSourceSupport.clearDataSource();而直接使用
RoutingDataSourceSupport.setDataSource(null);
相關文章
相關標籤/搜索