Spring动态配置多数据源

    技术2025-02-18  11

    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 -->     <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类 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();             } }

    最新回复(0)