Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况:
  一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。
  二是,非表级上的跨数据库。即,多个数据源不存在相同的表。
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。
  
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。

1. 数据源的名称常量类:
Java代码

  1. package com.test;   
  2. public class DataSourceMap {   
  3.     public static final String TEST="test";   
  4.     public static final String LJH="ljh";   
  5. }  

2. 建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称
Java代码

  1. package com.test;   
  2. public class CustomerContextHolder {   
  3.     private static final ThreadLocal<String> customer = new ThreadLocal<String>();// 线程本地环境   
  4.     // 设置数据源类型    
  5.     public static void setCustomerType(String customerType){   
  6.         customer.set(customerType);   
  7.     }   
  8.     // 获取数据源类型    
  9.     public static String getCustomerType(){   
  10.         return customer.get();   
  11.     }   
  12.     // 清除数据源类型    
  13.     public static void remove(){   
  14.         customer.remove();   
  15.     }   
  16. }  

3. 建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串
Java代码

  1. package com.test;   
  2. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;   
  3.   
  4. public class DynamicDataSource extends AbstractRoutingDataSource{   
  5.   
  6.     @Override  
  7.     protected Object determineCurrentLookupKey() {   
  8.         // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型   
  9.         return CustomerContextHolder.getCustomerType();   
  10.     }   
  11. }  

4. 编写spring的配置文件配置多个数据源
Java代码

  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   
  5.     <!-- 数据源公共的内容 -->    
  6.     <bean id="abstractDataSource"  
  7.         class="com.mchange.v2.c3p0.ComboPooledDataSource">   
  8.         <property name="user" value="root"></property>   
  9.         <property name="password" value="root"></property>   
  10.         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>   
  11.     </bean>   
  12.     <!-- 数据库ljh -->    
  13.     <bean id="ljhDataSource" parent="abstractDataSource" >   
  14.         <property name="jdbcUrl"  
  15.             value="jdbc:mysql://localhost:3306/ljh">   
  16.         </property>   
  17.     </bean>   
  18.     <!-- 数据库test -->    
  19.     <bean id="testDataSource" parent="abstractDataSource" >   
  20.         <property name="jdbcUrl"  
  21.             value="jdbc:mysql://localhost:3306/test">   
  22.         </property>   
  23.     </bean>   
  24.     <!-- 配置多数据源映射关系 -->    
  25.     <bean id="dataSource"    class="com.test.DynamicDataSource">   
  26.         <property name="targetDataSources">   
  27.             <map>   
  28.                 <entry key="ljh" value-ref="ljhDataSource"></entry>   
  29.             </map>   
  30.         </property>   
  31.         <property name="defaultTargetDataSource" ref="testDataSource"></property>   
  32.     </bean>    
  33.     <!-- sessionFactory的配置 -->    
  34.     <bean id="sessionFactory"  
  35.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  36.         <property name="dataSource">   
  37.             <ref bean="dataSource"/>    
  38.         </property>   
  39.         <!-- 实体类资源映射 -->    
  40.         <property name="mappingDirectoryLocations">   
  41.             <list>   
  42.                 <value>classpath:com/test</value>   
  43.             </list>   
  44.         </property>   
  45.         <!-- 为sessionFactory 配置Hibernate属性 -->    
  46.         <property name="hibernateProperties">   
  47.             <props>   
  48.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>   
  49.                 <prop key="hibernate.show_sql">true</prop>   
  50.             </props>   
  51.         </property>   
  52.     </bean>   
  53.     <!-- 为dao配置sessionFactory -->    
  54.     <bean id="userDaoImpl" class="com.test.UserDaoImpl">   
  55.         <property name="sessionFactory" ref="sessionFactory"></property>   
  56.     </bean>   
  57.        
  58. </beans>  

User类:
Java代码

  1. package com.test;  
  2. public class User {   
  3.     private Integer id;   
  4.     private String name;   
  5.        
  6.     public Integer getId() {   
  7.         return id;   
  8.     }   
  9.     public void setId(Integer id) {   
  10.         this.id = id;   
  11.     }   
  12.     public String getName() {   
  13.         return name;   
  14.     }   
  15.     public void setName(String name) {   
  16.         this.name = name;   
  17.     }   

user.hbm.xml文件:
Java代码

  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >   
  3. <hibernate-mapping>   
  4.     <class name="com.test.User" table="tuser">   
  5.         <id name="id">   
  6.             <generator class="native"></generator>   
  7.         </id>   
  8.         <property name="name" length="15"></property>   
  9.     </class>   
  10. </hibernate-mapping>  

Dao类
Java代码

  1. package com.test;   
  2. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;   
  3.   
  4. public class UserDaoImpl extends HibernateDaoSupport{   
  5.     public void save(User user){   
  6.         this.getHibernateTemplate().save(user);   
  7.     }   
  8. }  

测试类
Java代码

  1. package com.test;   
  2.   
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;   
  4.   
  5. public class Test {   
  6.     public static void main(String[] args) {   
  7.         ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");   
  8.            
  9.         CustomerContextHolder.setCustomerType(DataSourceMap.TEST);   
  10.         UserDaoImpl userDaoImpl = (UserDaoImpl)ctx.getBean("userDaoImpl");   
  11.         User user = new User();   
  12.         user.setName("test");   
  13.         userDaoImpl.save(user);   
  14.   
  15.         CustomerContextHolder.setCustomerType(DataSourceMap.LJH);   
  16.         user.setName("ljh");   
  17.         userDaoImpl.save(user);   
  18.         CustomerContextHolder.remove();   
  19.            
  20.     }    www.fkjava.org
  21. }