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");
上一篇:Sql Server,如何去含有非数字的nvarchar,再转为为数值


下一篇:基于springboot通过注解AOP动态切换druid多数据源--mybatis