Spring动态配置多数据源(转载)
Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况:
一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。
二是,非表级上的跨数据库。即,多个数据源不存在相同的表。
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。
1. 数据源的名称常量类:package com.test; public class DataSourceMap { public static final String TEST="test"; public static final String LJH="ljh"; }
2. 建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称
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,一般是返回字符串
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的配置文件配置多个数据源
<?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,继承abstractDataSource --> <bean id="ljhDataSource" parent="abstractDataSource" > <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ljh"> </property> </bean> <!-- 数据库test,继承abstractDataSource --> <bean id="testDataSource" parent="abstractDataSource" > <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"> </property> </bean> <!-- 配置多数据源映射关系,动态数据源类,注意,这个类必须继承AbstractRoutingDataSource --> <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类:
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文件:
<?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类
package com.test; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class UserDaoImpl extends HibernateDaoSupport{ public void save(User user){ this.getHibernateTemplate().save(user); } }
测试类
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(); } }
相关推荐
yangkang 2020-11-09
lbyd0 2020-11-17
sushuanglei 2020-11-12
85477104 2020-11-17
KANSYOUKYOU 2020-11-16
wushengyong 2020-10-28
lizhengjava 2020-11-13
星月情缘 2020-11-13
huangxiaoyun00 2020-11-13
luyong0 2020-11-08
腾讯soso团队 2020-11-06
Apsaravod 2020-11-05
PeterChangyb 2020-11-05
gaobudong 2020-11-04
wwwjun 2020-11-02
gyunwh 2020-11-02
EchoYY 2020-10-31
dingyahui 2020-10-30