在项目中使用多个数据源sessionfactory

    技术2026-01-12  4

    适用范围:适合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();}}

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

    最后一个关键类:用来存放当前正在使用的sessionFactorypublic 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);

    最新回复(0)