`
longgangbai
  • 浏览: 7252295 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【转】在项目中使用多个数据源-多sessionFactory方案

阅读更多

          适用范围:适合SSH架构访问多个数据库,数据库的类型和表结构不必相同,且没有跨库事务的情况(跨库事务最好用分布式事务处理)。

实现方式:我们可以在spring的配置文件中配置多个sessionFactory,如:
<bean id="aDataSource"

   class="org.apache.commons.dbcp.BasicDataSource"
   destroy-method="close">
   <property name="driverClassName">
    <value>${adriver}</value>
   </property>
   <property name="url">
    <value>${aurl}</value>
   </property>
   <property name="username">
    <value>${ausername}</value>
   </property>
   <property name="password">
    <value>${apassword}</value>
   </property>
</bean>
<bean id="bDataSource"
   class="org.apache.commons.dbcp.BasicDataSource"
   destroy-method="close">
   <property name="driverClassName">
    <value>${bdriver}</value>
   </property>
   <property name="url">
    <value>${burl}</value>
   </property>
   <property name="username">
    <value>${busername}</value>
   </property>
   <property name="password">
    <value>${bpassword}</value>
   </property>
</bean>
<bean id="cDataSource"
   class="org.apache.commons.dbcp.BasicDataSource"
   destroy-method="close">
   <property name="driverClassName">
    <value>${cdriver}</value>
   </property>
   <property name="url">
    <value>${curl}</value>
   </property>
   <property name="username">
    <value>${cusername}</value>
   </property>
   <property name="password">
    <value>${cpassword}</value>
   </property>
</bean>

<!-- Hibernate SessionFactorys -->
<bean id="aSessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource">
    <ref local="aDataSource" />
   </property>
   <property name="mappingResources">
    <list>
     <value>
      .hbm.xml文件
     </value>
    </list>
   </property>
   <property name="hibernateProperties">
    <props>
     <prop key="hibernate.dialect">
      ${ahibernate.dialect}
     </prop>
     <prop key="hibernate.show_sql">true</prop>
     <prop key="format_sql">true</prop>
    </props>
   </property>
</bean>

<bean id="bSessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource">
    <ref local="bDataSource" />
   </property>
   <property name="mappingResources">
    <list>
     <value>
      .hbm.xml文件
     </value>
    </list>
   </property>
   <property name="hibernateProperties">
    <props>
     <prop key="hibernate.dialect">
      ${bhibernate.dialect}
     </prop>
     <prop key="hibernate.show_sql">true</prop>
     <prop key="format_sql">true</prop>
    </props>
   </property>
</bean>

<bean id="cSessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource">
    <ref local="cDataSource" />
   </property>
   <property name="mappingResources">
    <list>
     <value>
       .hbm.xml文件
     </value>
    </list>
   </property>
   <property name="hibernateProperties">
    <props>
     <prop key="hibernate.dialect">
      ${chibernate.dialect}
     </prop>
     <prop key="hibernate.show_sql">true</prop>
     <prop key="format_sql">true</prop>
    </props>
   </property>
</bean>

<bean id="sessionFactory" class="com.cintel.dcp.datasource.MultiSessionFactory">
   <property name="sessionFactory"><ref local="aSessionFactory"/></property>
</bean>
注意:最后一个com.cintel.dcp.datasource.MultiSessionFactory要自己实现,它实现了SessionFactory接口和ApplicationContext接口,如下:
package com.cintel.dcp.datasource;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Map;
import java.util.Set;

import javax.naming.NamingException;
import javax.naming.Reference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.classic.Session;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.stat.Statistics;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class MultiSessionFactory implements SessionFactory, ApplicationContextAware {
private static final long serialVersionUID = 2064557324203496378L;
private static final Log log = LogFactory.getLog(MultiSessionFactory.class);
private ApplicationContext applicationContext = null;
private SessionFactory sessionFactory = null;

public ApplicationContext getApplicationContext() {
   return applicationContext;
}

public void setApplicationContext(ApplicationContext applicationContext) {
   this.applicationContext = applicationContext;
}

public SessionFactory getSessionFactory(String sessionFactoryName) {
   log.debug("sessionFactoryName:"+sessionFactoryName);
   try{
    if(sessionFactoryName==null||sessionFactoryName.equals("")){
     return sessionFactory;
    }
    return (SessionFactory)this.getApplicationContext().getBean(sessionFactoryName);
   }catch(NoSuchBeanDefinitionException ex){
    throw new RuntimeException("There is not the sessionFactory <name:"+sessionFactoryName+"> in the applicationContext!");
   }
}

public SessionFactory getSessionFactory() {
   String sessionFactoryName = CustomerContextHolder.getCustomerType();
   return getSessionFactory(sessionFactoryName);
}

public void setSessionFactory(SessionFactory sessionFactory) {
   this.sessionFactory = sessionFactory;
}


/* (non-Javadoc)
* @see org.hibernate.SessionFactory#close()
*/
public void close() throws HibernateException {
   getSessionFactory().close();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evict(java.lang.Class)
*/
public void evict(Class persistentClass) throws HibernateException {
   getSessionFactory().evict(persistentClass);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evict(java.lang.Class, java.io.Serializable)
*/
public void evict(Class persistentClass, Serializable id) throws HibernateException {
   getSessionFactory().evict(persistentClass, id);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictCollection(java.lang.String)
*/
public void evictCollection(String roleName) throws HibernateException {
   getSessionFactory().evictCollection(roleName);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictCollection(java.lang.String, java.io.Serializable)
*/
public void evictCollection(String roleName, Serializable id) throws HibernateException {
   getSessionFactory().evictCollection(roleName, id);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictEntity(java.lang.String)
*/
public void evictEntity(String entityName) throws HibernateException {
   getSessionFactory().evictEntity(entityName);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictEntity(java.lang.String, java.io.Serializable)
*/
public void evictEntity(String entityName, Serializable id) throws HibernateException {
   getSessionFactory().evictEntity(entityName, id);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictQueries()
*/
public void evictQueries() throws HibernateException {
   getSessionFactory().evictQueries();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#evictQueries(java.lang.String)
*/
public void evictQueries(String cacheRegion) throws HibernateException {
   getSessionFactory().evictQueries(cacheRegion);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getAllClassMetadata()
*/
public Map getAllClassMetadata() throws HibernateException {
   return getSessionFactory().getAllClassMetadata();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getAllCollectionMetadata()
*/
public Map getAllCollectionMetadata() throws HibernateException {
   return getSessionFactory().getAllCollectionMetadata();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getClassMetadata(java.lang.Class)
*/
public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException {
   return getSessionFactory().getClassMetadata(persistentClass);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getClassMetadata(java.lang.String)
*/
public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
   return getSessionFactory().getClassMetadata(entityName);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getCollectionMetadata(java.lang.String)
*/
public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException {
   return getSessionFactory().getCollectionMetadata(roleName);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getCurrentSession()
*/
public Session getCurrentSession() throws HibernateException {
   return getSessionFactory().getCurrentSession();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getDefinedFilterNames()
*/
public Set getDefinedFilterNames() {
   return getSessionFactory().getDefinedFilterNames();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getFilterDefinition(java.lang.String)
*/
public FilterDefinition getFilterDefinition(String filterName) throws HibernateException {
   return getSessionFactory().getFilterDefinition(filterName);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#getStatistics()
*/
public Statistics getStatistics() {
   return getSessionFactory().getStatistics();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#isClosed()
*/
public boolean isClosed() {
   return getSessionFactory().isClosed();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession()
*/
public Session openSession() throws HibernateException {
   return getSessionFactory().openSession();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(java.sql.Connection)
*/
public Session openSession(Connection connection) {
   return getSessionFactory().openSession(connection);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(org.hibernate.Interceptor)
*/
public Session openSession(Interceptor interceptor) throws HibernateException {
   return getSessionFactory().openSession(interceptor);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(java.sql.Connection, org.hibernate.Interceptor)
*/
public Session openSession(Connection connection, Interceptor interceptor) {
   return getSessionFactory().openSession(connection, interceptor);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openStatelessSession()
*/
public StatelessSession openStatelessSession() {
   return getSessionFactory().openStatelessSession();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openStatelessSession(java.sql.Connection)
*/
public StatelessSession openStatelessSession(Connection connection) {
   return getSessionFactory().openStatelessSession(connection);
}
/* (non-Javadoc)
* @see javax.naming.Referenceable#getReference()
*/
public Reference getReference() throws NamingException {
   return getSessionFactory().getReference();
}
}


然后我用一个常量类来标识sessionFactory
public class DynamicDataSourceType {
public static final String A= "aSessionFactory";
public static final String B= "bSessionFactory";
public static final String C= "cSessionFactory";
}

最后一个关键类:用来存放当前正在使用的sessionFactory
public class CustomerContextHolder {

private static final ThreadLocal contextHolder = new ThreadLocal();

public static void setCustomerType(String customerType) {
   Assert.notNull(customerType, "customerType cannot be null");
   contextHolder.set(customerType);
}

public static String getCustomerType() {
   return (String) contextHolder.get();
}

public static void clearCustomerType() {
   contextHolder.remove();
}
}

可以在action、service、dao中进行数据库切换,切换方式:
CustomerContextHolder.setCustomerType(DynamicDataSourceType.A);

分享到:
评论

相关推荐

    spring框架多数据源切换问题的解决

    首先,这个方案完全是在spring的框架下解决的,数据源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource属性,它甚至都不知道dataSource的改变。 其次,实现简单,易于维护。这个方案虽然我说...

    网站设计方案(完整版).doc

    Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在 Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架 构中取代CMP,完成数据持久化的重任。...

    Spring-Reference_zh_CN(Spring中文参考手册)

    处理多个持久化单元 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与其他web框架的集成 ...

    ssh(structs,spring,hibernate)框架中的上传下载

     第3~9行定义了一个数据源,其实现类是apache的BasicDataSource,第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值...

    spring chm文档

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    Spring.3.x企业应用开发实战(完整版).part2

    8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础知识 9.1.1 何为数据库事务 9.1.2 数据并发的问题 9.1.3 数据库锁机制 9.1.4 事务隔离...

    Spring3.x企业应用开发实战(完整版) part1

    8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础知识 9.1.1 何为数据库事务 9.1.2 数据并发的问题 9.1.3 数据库锁机制 9.1.4 事务隔离...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring API

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring 2.0 开发参考手册

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    轻量级数据持久层组件Restful.Data.zip

    下载Restful.dll、Restful.Data、Restful.Data.MySql、Remotion.Linq.dll、MySql.Data.dll,或者直接下载源代码进行编译并获取这5个dll,并在项目中引用这些dll。在 Web.config 或 App.config 中配置连接字符串,...

    springmybatis

    而且也比较轻量级,因为当时在项目中,没来的及做很很多笔记。后来项目结束了,我也没写总结文档。已经过去好久了。但最近突然又对这个ORM 工具感兴趣。因为接下来自己的项目中很有可能采用这个ORM工具。所以在此...

Global site tag (gtag.js) - Google Analytics