Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况:
一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。
二是,非表级上的跨数据库。即,多个数据源不存在相同的表。
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。
1. 数据源的名称常量类:
Java代码
- package com.test;
- public class DataSourceMap {
- public static final String TEST="test";
- public static final String LJH="ljh";
- }
2. 建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称
Java代码
- package com.test;
- public class CustomerContextHolder {
- private static final ThreadLocal<String> customer = new ThreadLocal<String>();// 线程本地环境
- // 设置数据源类型
- public static void setCustomerType(String customerType){
- customer.set(customerType);
- }
- // 获取数据源类型
- public static String getCustomerType(){
- return customer.get();
- }
- // 清除数据源类型
- public static void remove(){
- customer.remove();
- }
- }
3. 建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串
Java代码
- package com.test;
- import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
- public class DynamicDataSource extends AbstractRoutingDataSource{
- @Override
- protected Object determineCurrentLookupKey() {
- // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型
- return CustomerContextHolder.getCustomerType();
- }
- }
4. 编写spring的配置文件配置多个数据源
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
- <!-- 数据源公共的内容 -->
- <bean id="abstractDataSource"
- class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <property name="user" value="root"></property>
- <property name="password" value="root"></property>
- <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
- </bean>
- <!-- 数据库ljh -->
- <bean id="ljhDataSource" parent="abstractDataSource" >
- <property name="jdbcUrl"
- value="jdbc:mysql://localhost:3306/ljh">
- </property>
- </bean>
- <!-- 数据库test -->
- <bean id="testDataSource" parent="abstractDataSource" >
- <property name="jdbcUrl"
- value="jdbc:mysql://localhost:3306/test">
- </property>
- </bean>
- <!-- 配置多数据源映射关系 -->
- <bean id="dataSource" class="com.test.DynamicDataSource">
- <property name="targetDataSources">
- <map>
- <entry key="ljh" value-ref="ljhDataSource"></entry>
- </map>
- </property>
- <property name="defaultTargetDataSource" ref="testDataSource"></property>
- </bean>
- <!-- sessionFactory的配置 -->
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource"/>
- </property>
- <!-- 实体类资源映射 -->
- <property name="mappingDirectoryLocations">
- <list>
- <value>classpath:com/test</value>
- </list>
- </property>
- <!-- 为sessionFactory 配置Hibernate属性 -->
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
- <prop key="hibernate.show_sql">true</prop>
- </props>
- </property>
- </bean>
- <!-- 为dao配置sessionFactory -->
- <bean id="userDaoImpl" class="com.test.UserDaoImpl">
- <property name="sessionFactory" ref="sessionFactory"></property>
- </bean>
- </beans>
User类:
Java代码
- package com.test;
- public class User {
- private Integer id;
- private String name;
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
user.hbm.xml文件:
Java代码
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
- <hibernate-mapping>
- <class name="com.test.User" table="tuser">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="name" length="15"></property>
- </class>
- </hibernate-mapping>
Dao类
Java代码
- package com.test;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- public class UserDaoImpl extends HibernateDaoSupport{
- public void save(User user){
- this.getHibernateTemplate().save(user);
- }
- }
测试类
Java代码
- package com.test;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class Test {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- CustomerContextHolder.setCustomerType(DataSourceMap.TEST);
- UserDaoImpl userDaoImpl = (UserDaoImpl)ctx.getBean("userDaoImpl");
- User user = new User();
- user.setName("test");
- userDaoImpl.save(user);
- CustomerContextHolder.setCustomerType(DataSourceMap.LJH);
- user.setName("ljh");
- userDaoImpl.save(user);
- CustomerContextHolder.remove();
- } www.fkjava.org
- }
















