mybatis切換多數據源

引語

有時候咱們須要切換多個數據源,來使用不一樣的數據,這時候咱們可使用mybatis的DataSourceTransactionManager來實現數據源的切換. 下面咱們一塊兒來看下來一個簡單的實現方式.php

步驟:

1.首先咱們jdbc.properties(名字不必定是這個,代指保存數據庫鏈接信息的配置文件)裏面有多個數據源,一個老的一個新的java

jdbc.driver:com.mysql.Driver
jdbc.url:xxx
jdbc.username:xxx
jdbc.password:xxx

old.jdbc.driver:com.mysql.Driver
old.jdbc.url:xxx
old.jdbc.username:xxx
old.jdbc.password:xxx
複製代碼

2.寫一個CustomerContextHolder,裏面的屬性ThreadLocal保存的就是當前數據源的key,每個數據源對應一個key,這裏默認是新數據庫-new,另外一個是老數據庫-oldmysql

public class CustomerContextHolder {
    public static final String DATA_SOURCE_DEFAULT = "new";
    public static final String DATA_SOURCE_OLD = "old";
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setCustomerType(String customerType) {
        contextHolder.set(customerType);
    }

    public static String getCustomerType() {
        return contextHolder.get();
    }

    public static void clearCustomerType() {
        contextHolder.remove();
    }
}
複製代碼

3.寫一個叫DynamicDataSource的類,繼承AbstractRoutingDataSource,AbstractRoutingDataSource裏面有一個determineCurrentLookupKey方法,是決定 使用哪一個數據源key.(至關於說每一個數據源有一個key的標識,返回不一樣的key就是選擇了不一樣的數據源).web

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return CustomerContextHolder.getCustomerType();
    }

}
複製代碼

4.而後將spring-datasource.xml的配置配好spring

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-lazy-init="true">

    <!-- DataSource數據 -->
    <bean id="newDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="name" value="wxwwt"/>
        <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="20"/>
        <property name="minIdle" value="2"/>
        <property name="initialSize" value="2"/>
        <property name="validationQuery" value="SELECT 1"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="testWhileIdle" value="true"/>
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <property name="minEvictableIdleTimeMillis" value="300000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="logAbandoned" value="true"/>
        <property name="filters" value="stat"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wxwwt.web.db.mapper"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="mapperLocations">
            <list>
                <value>classpath*:sqlmap/**/*.xml</value>
            </list>
        </property>
        <property name="dataSource" ref="dynamicDataSource"/>

    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

    <bean id="oldDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="name" value="wxwwt"/>
        <property name="driverClassName" value="${old.jdbc.driver}"/>
        <property name="url" value="${old.jdbc.url}"/>
        <property name="username" value="${old.jdbc.username}"/>
        <property name="password" value="${old.jdbc.password}"/>
        <property name="maxActive" value="20"/>
        <property name="minIdle" value="2"/>
        <property name="initialSize" value="2"/>
        <property name="validationQuery" value="SELECT 1"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="testWhileIdle" value="true"/>
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <property name="minEvictableIdleTimeMillis" value="300000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="logAbandoned" value="true"/>
        <property name="filters" value="stat"/>
    </bean>

    <!-- 動態數據源 -->
    <bean id="dynamicDataSource" class="com.wxwwt.web.config.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry value-ref="newDataSource" key="new"/>
                <entry value-ref="oldDataSource" key="old"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="newDataSource">
        </property>
    </bean>


    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dynamicDataSource"/>
    </bean>
</beans>
複製代碼

裏面配置好數據源newDataSource,oldDataSource.重點是dynamicDataSource裏面配置好擁有的數據源, 而後將dynamicDataSource配置到DataSourceTransactionManager裏面就大功告成了.sql

5.使用的使用只須要數據庫

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_OLD);
複製代碼

切換到老數據源,由於默認是新數據源. 若是要切換回來就bash

CustomerContextHolder.clearCustomerType();
複製代碼

清除掉ThreadLocal中保存的信息.又由於切換數據源的key是在ThreadLocal中的因此是隻和線程有關, 一個線程選擇老數據源,並不會影響到其餘的線程.mybatis

相關文章
相關標籤/搜索