最近做个小项目,spring mvc的,有个数据源切换的问题是以前没有遇到的,在网上搜索还是有很多关于这方面的问题,这里我也把我我写的代码贴出来,有写得不好的地方希望在评论区多指教。
上代码:
1.先创建一个jdbc.properties文件用来写多数据源的驱动,密码等信息:
# MySQL1
#============================================================================
jdbc.driver-singlefile=com.mysql.jdbc.Driver
jdbc.url-singlefile=jdbc:mysql://127.0.0.1:3306/singlefile?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=true
jdbc.username-singlefile=root
jdbc.password-singlefile=windows
# MySQL2
#============================================================================
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/newcreatedb?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=true
jdbc.username=root
jdbc.password=windows
#
#============================================================================
jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxIdle=20
jdbc.maxActive=100
jdbc.maxWait=100000
2.在我们的配置文件spring-dao.xml文件里面配置读取信息:
<!-- 配置整合mybatis过程 -->
<!-- 1.开始设置双数据源 -->
<context:property-placeholder location="classpath:spring/jdbcNew.properties" />
<!-- 配置第一个数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver-singlefile}" />
<property name="url" value="${jdbc.url-singlefile}" />
<property name="username" value="${jdbc.username-singlefile}" />
<property name="password" value="${jdbc.password-singlefile}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${jdbc.initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${jdbc.maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${jdbc.minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${jdbc.maxWait}"></property>
</bean>
<!--配置第二个数据源-->
<bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<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="initialSize" value="${jdbc.initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${jdbc.maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${jdbc.minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${jdbc.maxWait}"></property>
</bean>
<!--统一的dataSource-->
<bean id="dynamicDataSource" class="com.singlefile.tool.DynamicDataSource" >
<property name="targetDataSources">
<map key-type="java.lang.String">
<!--通过不同的key决定用哪个dataSource-->
<entry value-ref="dataSource" key="dataSource"></entry>
<entry value-ref="mysqlDataSource" key="mysqlDataSource"></entry>
</map>
</property>
<!--设置默认的dataSource-->
<property name="defaultTargetDataSource" ref="dataSource">
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dynamicDataSource" />
</bean>
注意:配置文件中的 "统一的dataSource"那个地方,下面配置的类文件路径,是我下面要贴出的代码的文件,你在写的时候需要填写你的路径
3.下面需要配置另外一个spring-service.xml文件:
注意每一个dataSource的名称不要配置错了,不然报各种各种的错误。
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫描service包下所有使用注解的类型 -->
<context:component-scan base-package="com.singlefile.service" />
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<!-- <property name="dataSource" ref="dataSource" /> -->
<property name="dataSource" ref="dynamicDataSource" />
</bean>
</beans>
4.配置完下面看一下我们刚说的那个类:DynamicDataSource.java,上代码:
public class DynamicDataSource extends AbstractRoutingDataSource {
//本地线程,获取当前正在执行的currentThread
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();
}
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
5.写完上面那一步以后我们需要写切换我们的数据源的代码,需要在写一个类:
public class CustomerContextHolder {
public static final String DATA_SOURCE_A = "dataSource";
public static final String DATA_SOURCE_B = "mysqlDataSource";
//用ThreadLocal来设置当前线程使用哪个dataSource
private 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();
}
}
代码写到这里,基本上就配置完了,至于你想在那个层切换数据源看你的需求和意向了。
在想要切换数据源的地方写出如下代码就完成了切换:
DynamicDataSource.clearCustomerType();
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);
到此本次数据源切换的功能就做完了,欢迎多指教。