`
sbpya
  • 浏览: 615529 次
  • 性别: 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);

 

以上思路来自javaEye论坛的一个高手,在此标识感谢

 

 

 

 

 

 ------------------------------------------------------------ 个人觉得此思路还是不错,如果能加分布务事务一并封装进去,是不是会更好一点? </name:>

分享到:
评论

相关推荐

    springmvc_mybatis_多数据源

    当项目需求涉及到多个数据源时,如何在SpringMVC和MyBatis中配置和管理这些数据源就成为了一个关键问题。"springmvc_mybatis_多数据源"这个项目就是针对这种情况提供的一种解决方案。 首先,我们来看SpringMVC如何...

    Spring多数据源解决方案

    Spring多数据源解决方案是针对大型应用中数据分片和分布式数据库管理的需求而设计的一种策略。...在实际项目中,可以根据具体需求进行定制,例如使用更复杂的上下文判断规则,或者实现更高效的数据源切换策略。

    如何在spring框架中解决多数据源的问题

    在实际的软件开发过程中,尤其是在企业级应用开发中,经常会遇到需要同时处理多个数据源的情况。例如,一个应用程序可能需要同时访问Oracle数据库和MySQL数据库,或者根据业务逻辑的不同阶段选择不同的数据源。这种...

    spring如何实现注入多个数据源[归类].pdf

    在Spring框架中实现多个数据源的注入,主要是为了解决项目中需要连接并动态切换不同数据库的需求。这种需求通常出现在多租户系统或者需要对不同客户提供差异化服务的场景。以下是一种基于Decorator设计模式的解决...

    spring+hibernate+atomikos多数据源

    在多数据源环境中,Hibernate可以通过SessionFactory配置多个数据源,每个数据源对应一个SessionFactory。 3. **Atomikos**: Atomikos是一个开源的JTA(Java Transaction API)实现,提供分布式事务管理服务。在...

    Ssh多数据源.doc

    在配置方面,通常我们会创建多个数据源实例,每个实例对应一个特定的数据库。例如,这里使用了c3p0连接池组件(com.mchange.v2.c3p0.ComboPooledDataSource),它提供了高效且可靠的数据库连接管理。c3p0通过连接池...

    spring+hibernate和spring+myBatis实现连接多个数据库,同时操作的项目

    在多数据源环境中,MyBatis的配置文件需要包含多个数据源的信息,每次操作数据库时,可以通过SqlSessionFactoryBuilder创建指定数据源的SqlSessionFactory,然后通过SqlSession来执行SQL。 项目的...

    sping多数据源动态切换

    这里,我们配置了两个数据源`springMvcDemo`和`czcTest`,并将它们映射到`targetDataSources`的Map中。 在实际应用中,动态数据源的使用相当直观。尽管`DynamicDataSource`是动态的,但它仍可像普通`DataSource`...

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

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

    hibernate同时配置多个数据库连接

    - **使用DataSource**:如果使用Java的JNDI数据源,可以将多个数据库的连接信息配置在应用服务器中,然后在Hibernate配置文件中引用这些数据源。 6. **性能优化** - **连接池管理**:为了提高性能,建议为每个...

    Spring Boot 集成Mybatis实现主从(多数据源)分离方案示例

    在MyBatis配置文件中,需要配置多个数据源的SessionFactory,以便在应用程序中使用不同的数据源。同时,需要配置Mapper文件,以便将SQL语句映射到对应的数据源上。 在应用程序中,需要使用tk.mybatis Mapper来映射...

    新Hibernate SessionFactory().getCurrentSession()猫腻

    在实际开发中,如果对这个方法的内部机制不熟悉,可能会导致并发问题,比如多个线程共享同一个Session,或者在没有正确配置事务管理时引发异常。 接下来,我们看看标签“源码”和“工具”,这表明讨论可能涉及到...

    如何在一个WEB程序里同时连接多个数据库

    1. **事务管理**:当涉及到多个数据源时,需要注意事务的一致性问题。如果多个操作跨越不同的数据源,可能需要手动管理事务。 2. **性能优化**:连接池的合理配置对于性能至关重要,比如最大连接数、空闲时间等。 3....

    HibernateSpring多数据库解决方案.doc

    总结起来,这个多数据库解决方案利用Spring的IoC容器管理和配置了多个数据源,同时结合Hibernate提供了ORM功能。通过`OpenSessionInView`模式,确保了Web请求中的持久化操作能在合适的Session上下文中进行。这样的...

    诺祺skyon-webframe相关问题

    Skyon-WebFrame可能会提供统一的事务管理机制,确保在多个数据源间的操作一致性。 5. **配置双数据源**:这涉及到在框架的配置文件中定义两个或更多的数据源,并指定每个数据源的连接信息,如URL、用户名、密码等。...

    基于hibernate的mysql分表分库实例-mysql-cluster-hibernate.zip

    在实际应用中,为了利用Hibernate的ORM优势并结合MySQL集群的高可用性,开发者需要配置Hibernate以适应多数据源环境。这通常涉及到创建多个SessionFactory实例,每个实例对应一个数据库实例。同时,可能需要自定义...

    HIbernate与oracle数据库应用例子

    Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为开发者提供了在Java应用中操作数据库的强大工具。通过ORM,开发者可以使用面向对象的方式来处理数据,而无需直接编写SQL语句。这大大提高了开发效率并降低...

    j2ee高级框架实战教学视频源代码11-20.rar

    这部分可能涉及到Tiles定义、配置和如何在JSP中使用Tiles定义来组合页面。 9. **16Hibernate基本API**:这部分内容可能包括了对Hibernate核心API的介绍,如SessionFactory、Session、Query接口的使用方法,以及如何...

Global site tag (gtag.js) - Google Analytics