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>
<!--
<!– ===============第二个数据源的配置=============== –>
<!– MyBatis配置 –>
<bean id="sqlSessionFactory_slave" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource_tow" />
<!– 自动扫描entity目录, 省掉Configuration.xml里的手工配置 –>
<property name="typeAliasesPackage" value="com.overcloud.pay.entity;com.overcloud.pay.vo" />
<!– 显式指定Mapper文件位置 –>
<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>
<!– 使用annotation定义事务 –>
<bean id="transactionManager_tow" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource_tow"></property>
</bean>
<!– 使用annotation定义事务 –>
<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();
}
}