springmvc 配置多个数据源,并动态切换

前言:工作中经常会有两个数据源的情况,所以记录一下。这里测试两个数据源,给出流程和代码。

首先:配置两个数据源

    <description>配置mybatis数据源</description>

    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath*:conf/system/*.properties"/>

    <!-- 需要 commons.dbcp 包 -->
    <bean id="firstDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${db.driver}"/>
        <property name="url" value="${db.datasourceurl}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>

        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="20"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="validationQuery" value="select count(*) from dual"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <property name="testWhileIdle" value="true"/>
    </bean>

    <!--数据源二-->
    <bean id="secondDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${second.db.driver}"/>
        <property name="url" value="${second.db.datasourceurl}"/>
        <property name="username" value="${second.db.username}"/>
        <property name="password" value="${second.db.password}"/>

        <property name="maxActive" value="100"/>
        <property name="maxIdle" value="20"/>
        <property name="maxWait" value="1000"/>
        <property name="defaultAutoCommit" value="true"/>
        <property name="removeAbandoned" value="true"/>
        <property name="removeAbandonedTimeout" value="60"/>
        <property name="validationQuery" value="select count(*) from dual"/>
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <property name="testWhileIdle" value="true"/>
    </bean>

然后写一个数据源持有类

package com.yule.system.datasource;

/**
 * 数据源持有类
 * @author yule
 * @date 2018/9/28 19:34
 */
public class DataSourceHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    /**
     * @Description: 设置数据源类型
     * @param dataSourceType  数据库类型
     * @return void
     * @throws
     */
    public static void setDataSourceType(String dataSourceType) {
        contextHolder.set(dataSourceType);
    }

    /**
     * @Description: 获取数据源类型
     * @return String
     * @throws
     */
    public static String getDataSourceType() {
        return contextHolder.get();
    }

    /**
     * @Description: 清除数据源类型
     * @return void
     * @throws
     */
    public static void clearDataSourceType() {
        contextHolder.remove();
    }

}

然后:写一个数据源路由类

package com.yule.system.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 路由类
 * @author yule
 * @date 2018/9/28 19:29
 */
public class RoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDataSourceType();
    }
}

然后:配置数据源路由,class指定刚才的路由类

    <!--配置数据源路由-->
    <bean id="dataSource" class="com.yule.system.datasource.RoutingDataSource">
        <!-- 为targetDataSources注入两个数据源 -->
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="db1" value-ref="firstDataSource"/>
                <entry key="db2" value-ref="secondDataSource"/>
            </map>
        </property>
        <!-- 为指定数据源RoutingDataSource注入默认的数据源-->
        <property name="defaultTargetDataSource" ref="firstDataSource"/>
    </bean>

 然后:配置事务

    <!-- 自动注册service 必须在配置事务之上,否则@Transactional不起作用-->
    <context:component-scan base-package="com.yule">
        <context:include-filter type="regex" expression=".*.service..*" />
    </context:component-scan>

    <!--配置事务-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 支持注解形式 enable transaction annotation support -->
    <tx:annotation-driven transaction-manager="txManager" />

然后:整合 spring 合 mybatis

    <!-- mybatis为spring提供的jar,其配置时不支持正则表达式配置 -->
    <bean id="mySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.yule.*.entity,com.yule.*.*.entity,com.yule.*.*.*.entity"/>
        <property name="configLocation" value="classpath:/mybatis/system/mybatis-configuration.xml"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.yule.*.dao,com.yule.*.*.dao,com.yule.*.*.*.dao"/>
        <property name="sqlSessionFactoryBeanName" value="mySqlSessionFactory"/>
    </bean>

最后:使用方法

//获取数据源类型
DataSourceHolder.getDataSourceType();
//设置为 db1 的数据源
DataSourceHolder.setDataSourceType("db1");
//设置为 db2 的数据源
DataSourceHolder.setDataSourceType("db2");
原文地址:https://www.cnblogs.com/yuxiaole/p/9720480.html