2014-04-16 16:37:49

Spring 多数据源配置

DatabaseContextHolder.java
public class DatabaseContextHolder {
	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();
	}
}

DataSourceInterceptor.java

import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
@Component
public class DataSourceInterceptor {
	public void setdataSourceOne(JoinPoint jp) {
		DatabaseContextHolder.setCustomerType("jwDataSource");
	}
	public void setdataSourceTwo(JoinPoint jp) {
		DatabaseContextHolder.setCustomerType("jwDataSource2");
	}
}

DynamicDataSource.java

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
	@Override
	protected Object determineCurrentLookupKey() {
		return DatabaseContextHolder.getCustomerType();
	}
}

测试类:

重点是切换数据源,一般很少切,切换后记得切回去。或者给对应业务配置个AOP不然会很麻烦。

DatabaseContextHolder.setCustomerType("jwDataSource2");

DatabaseContextHolder.clearCustomerType();

import java.util.List;
import javax.annotation.Resource;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class JobDAO {
	@Resource
	private JdbcTemplate jdbcTemplate;
	public void test1() {
		String a = jdbcTemplate.queryForObject("select database()",String.class);
		System.out.println(a);
	}
	public synchronized void test2() {
		DatabaseContextHolder.setCustomerType("jwDataSource2");
		String a = jdbcTemplate.queryForObject("select database()",String.class);
		System.out.println(a);
		DatabaseContextHolder.clearCustomerType();
	}
}

核心的applicationContext.xml配置:

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.2.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
      http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task-3.2.xsd">
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/templates/">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
	</bean>
	<context:component-scan base-package="com.javaweb.test.*" />
	<tx:annotation-driven />
	<bean id="jwDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/test1?autoReconnect=true&amp;zeroDateTimeBehavior=round&amp;useUnicode=true&amp;characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
		<!--initialSize: 初始化连接 -->
		<property name="initialSize" value="5" />
		<!--maxIdle: 最大空闲连接 -->
		<property name="maxIdle" value="10" />
		<!--minIdle: 最小空闲连接 -->
		<property name="minIdle" value="5" />
		<!--maxActive: 最大连接数量 -->
		<property name="maxActive" value="15" />
		<!--removeAbandoned: 是否自动回收超时连接 -->
		<property name="removeAbandoned" value="true" />
		<!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
		<property name="removeAbandonedTimeout" value="180" />
		<!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
		<property name="maxWait" value="3000" />
		<property name="validationQuery">
			<value>SELECT 1</value>
		</property>
		<property name="testOnBorrow">
			<value>true</value>
		</property>
	</bean>
	<bean id="jwDataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/test2?autoReconnect=true&amp;zeroDateTimeBehavior=round&amp;useUnicode=true&amp;characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
		<!--initialSize: 初始化连接 -->
		<property name="initialSize" value="5" />
		<!--maxIdle: 最大空闲连接 -->
		<property name="maxIdle" value="10" />
		<!--minIdle: 最小空闲连接 -->
		<property name="minIdle" value="5" />
		<!--maxActive: 最大连接数量 -->
		<property name="maxActive" value="15" />
		<!--removeAbandoned: 是否自动回收超时连接 -->
		<property name="removeAbandoned" value="true" />
		<!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
		<property name="removeAbandonedTimeout" value="180" />
		<!--maxWait: 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
		<property name="maxWait" value="3000" />
		<property name="validationQuery">
			<value>SELECT 1</value>
		</property>
		<property name="testOnBorrow">
			<value>true</value>
		</property>
	</bean>
	<bean id="dynamicDataSource" class="com.javaweb.test.common.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry value-ref="jwDataSource" key="jwDataSource"></entry>
				<entry value-ref="jwDataSource2" key="jwDataSource2"></entry>
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="jwDataSource">
		</property>
	</bean>
	<!-- jdbcTemplate Spring JDBC 模版 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false" lazy-init="false" autowire="default">
		<property name="dataSource" ref="dynamicDataSource" />
	</bean>
	<!-- mvc注解与json连接器 -->
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
	<mvc:default-servlet-handler />
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="messageConverters">
			<list>
				<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
					<property name="supportedMediaTypes">
						<list>
							<value>application/json;charset=UTF-8</value>
						</list>
					</property>
				</bean>
			</list>
		</property>
	</bean>
	<!-- 上传拦截,如最大上传值及最小上传值 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="100000" />
	</bean>
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dynamicDataSource" />
	</bean>
	<aop:config>
		<aop:advisor pointcut="execution(public * com.javaweb.test.*.*(..))" advice-ref="txAdvice" />
	</aop:config>
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED" />
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>
</beans>

参考:http://blog.csdn.net/wangpeng047/article/details/8866239、http://blog.csdn.net/fhd001/article/details/6788304

发表回复