MyBatis 配置多数据源实现多个数据库动态切换

1.配置properties路径

我的配置文件

2.配置mybatis数据源

配置 第二套数据源

3 动态数据源的配置

两个key分别引入了 两套数据源,默认使用jsdx_telecom

4.配置SqlSessionFactory对象

5.配置事物管理器,要扫描的basePackage接口 

6.创建一个类取名为DynamicDataSource 继承AbstractRoutingDataSource

7  CustomerContextHolder类

使用方法:只需要在service层调用CustomerContextHolder方法的setCustomerType方法,传入要使用的数据源就好了。

PS:在这里有一个坑 我的两套数据源都是用的一个连接上的两个不同的数据库。所以数据源2的账号密码和数据源1的使用的是相同的prop字段,我试过使用不同的字段,很遗憾报错了。如果是两个不同的数据库应该不会存在这个问题 下边附完整的配置和java代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <description>Spring公共配置 </description>

    <!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
    <context:component-scan base-package="com.overcloud.pay.*" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
    </context:component-scan>


    <!-- 数据源配置, 使用Tomcat JDBC连接池 -->
    <bean id="jsdx_telecom" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <!-- Connection Info -->
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

        <!-- Connection Pooling Info -->
        <property name="maxActive" value="${jdbc.pool.maxActive}" />
        <property name="maxIdle" value="${jdbc.pool.maxIdle}" />
        <property name="minIdle" value="0" />
        <property name="defaultAutoCommit" value="false" />
    </bean>

    <!--第二套数据库配置-->
    <bean id="jsdx_url" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <!-- Connection Info -->
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url_tow}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

        <!-- Connection Pooling Info -->
        <property name="maxActive" value="${jdbc.pool.maxActive}" />
        <property name="maxIdle" value="${jdbc.pool.maxIdle}" />
        <property name="minIdle" value="0" />
        <property name="defaultAutoCommit" value="false" />
    </bean>

    <!--动态数据源的配置-->
    <bean id="dynamicDataSource" class="com.overcloud.pay.common.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry value-ref="jsdx_telecom" key="jsdx_telecom"/>
                <entry value-ref="jsdx_url" key="jsdx_url"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="jsdx_telecom">
        </property>
    </bean>

    <!-- 配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dynamicDataSource"/>
        <!-- 扫描model包 使用别名 -->
        <property name="typeAliasesPackage" value="com.overcloud.pay.entity;com.overcloud.pay.vo"/>
        <!-- 扫描sql配置文件:mapper需要的xml文件 -->
        <!-- <property name="mapperLocations" value="classpath:mapper/*.xml"/>-->
        <property name="mapperLocations" value="classpath:/mybatis/*/*Mapper.xml"/>
        <property name="configurationProperties">
            <props>
                <prop key="mapUnderscoreToCamelCase">true</prop>
            </props>
        </property>

    </bean>

    <!-- 扫描basePackage接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.overcloud.pay.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dynamicDataSource"/>
    </bean>

    <!-- 配置基于注解的声明式事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

    <!-- Enables the Spring Task @Scheduled programming model -->  
    <task:executor id="executor" pool-size="5" />  
    <task:scheduler id="scheduler" pool-size="10" />  
    <task:annotation-driven executor="executor" scheduler="scheduler" />

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





<!--
    &lt;!&ndash; ===============第二个数据源的配置=============== &ndash;&gt;

    &lt;!&ndash; MyBatis配置 &ndash;&gt;
    <bean id="sqlSessionFactory_slave" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource_tow" />
        &lt;!&ndash; 自动扫描entity目录, 省掉Configuration.xml里的手工配置 &ndash;&gt;
        <property name="typeAliasesPackage" value="com.overcloud.pay.entity;com.overcloud.pay.vo" />
        &lt;!&ndash; 显式指定Mapper文件位置 &ndash;&gt;
        <property name="mapperLocations" value="classpath:/mybatis/*/*Mapper.xml" />
    </bean>

    <bean id="sqlSessionTemplate_two" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory_slave" />
        <constructor-arg index="1" value="BATCH" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.overcloud.pay.dao_two" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory_slave"/>
    </bean>

    &lt;!&ndash; 使用annotation定义事务 &ndash;&gt;
    <bean id="transactionManager_tow" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource_tow"></property>
    </bean>
    &lt;!&ndash; 使用annotation定义事务 &ndash;&gt;
    <tx:annotation-driven transaction-manager="transactionManager_tow" proxy-target-class="true" />-->


    <!-- production环境 -->
    <beans profile="production">
        <context:property-placeholder ignore-unresolvable="true" location="classpath:userdefined.properties,classpath:datasource.properties" />
    </beans>

    <!-- test环境 -->
    <beans profile="test">
        <context:property-placeholder ignore-unresolvable="true" location="classpath*:datasource.test.properties" />
    </beans>
</beans>

java代码

package com.overcloud.pay.common;

public class CustomerContextHolder {
    public static final String DATASOURCE_TELECOM = "jsdx_telecom";
    public static final String DATASOURCE_URL = "jsdx_url";

    public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

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

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

    public static void clearCustomerType() {
        contextHolder.remove();
    }

}
package com.overcloud.pay.common;

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

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        System.out.println(CustomerContextHolder.getCustomerType());
        return CustomerContextHolder.getCustomerType();
    }
}
 

猜你喜欢

转载自blog.csdn.net/qq_37612755/article/details/82908700