最近做个小项目,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);

到此本次数据源切换的功能就做完了,欢迎多指教。

Logo

更多推荐