适用范围:适合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:>
3983

被折叠的 条评论
为什么被折叠?



