适用范围:适合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如何...
Spring多数据源解决方案是针对大型应用中数据分片和分布式数据库管理的需求而设计的一种策略。...在实际项目中,可以根据具体需求进行定制,例如使用更复杂的上下文判断规则,或者实现更高效的数据源切换策略。
在实际的软件开发过程中,尤其是在企业级应用开发中,经常会遇到需要同时处理多个数据源的情况。例如,一个应用程序可能需要同时访问Oracle数据库和MySQL数据库,或者根据业务逻辑的不同阶段选择不同的数据源。这种...
在Spring框架中实现多个数据源的注入,主要是为了解决项目中需要连接并动态切换不同数据库的需求。这种需求通常出现在多租户系统或者需要对不同客户提供差异化服务的场景。以下是一种基于Decorator设计模式的解决...
在多数据源环境中,Hibernate可以通过SessionFactory配置多个数据源,每个数据源对应一个SessionFactory。 3. **Atomikos**: Atomikos是一个开源的JTA(Java Transaction API)实现,提供分布式事务管理服务。在...
在配置方面,通常我们会创建多个数据源实例,每个实例对应一个特定的数据库。例如,这里使用了c3p0连接池组件(com.mchange.v2.c3p0.ComboPooledDataSource),它提供了高效且可靠的数据库连接管理。c3p0通过连接池...
在多数据源环境中,MyBatis的配置文件需要包含多个数据源的信息,每次操作数据库时,可以通过SqlSessionFactoryBuilder创建指定数据源的SqlSessionFactory,然后通过SqlSession来执行SQL。 项目的...
这里,我们配置了两个数据源`springMvcDemo`和`czcTest`,并将它们映射到`targetDataSources`的Map中。 在实际应用中,动态数据源的使用相当直观。尽管`DynamicDataSource`是动态的,但它仍可像普通`DataSource`...
首先,这个方案完全是在spring的框架下解决的,数据源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource属性,它甚至都不知道dataSource的改变。 其次,实现简单,易于维护。这个方案虽然我说...
- **使用DataSource**:如果使用Java的JNDI数据源,可以将多个数据库的连接信息配置在应用服务器中,然后在Hibernate配置文件中引用这些数据源。 6. **性能优化** - **连接池管理**:为了提高性能,建议为每个...
在MyBatis配置文件中,需要配置多个数据源的SessionFactory,以便在应用程序中使用不同的数据源。同时,需要配置Mapper文件,以便将SQL语句映射到对应的数据源上。 在应用程序中,需要使用tk.mybatis Mapper来映射...
在实际开发中,如果对这个方法的内部机制不熟悉,可能会导致并发问题,比如多个线程共享同一个Session,或者在没有正确配置事务管理时引发异常。 接下来,我们看看标签“源码”和“工具”,这表明讨论可能涉及到...
1. **事务管理**:当涉及到多个数据源时,需要注意事务的一致性问题。如果多个操作跨越不同的数据源,可能需要手动管理事务。 2. **性能优化**:连接池的合理配置对于性能至关重要,比如最大连接数、空闲时间等。 3....
总结起来,这个多数据库解决方案利用Spring的IoC容器管理和配置了多个数据源,同时结合Hibernate提供了ORM功能。通过`OpenSessionInView`模式,确保了Web请求中的持久化操作能在合适的Session上下文中进行。这样的...
Skyon-WebFrame可能会提供统一的事务管理机制,确保在多个数据源间的操作一致性。 5. **配置双数据源**:这涉及到在框架的配置文件中定义两个或更多的数据源,并指定每个数据源的连接信息,如URL、用户名、密码等。...
在实际应用中,为了利用Hibernate的ORM优势并结合MySQL集群的高可用性,开发者需要配置Hibernate以适应多数据源环境。这通常涉及到创建多个SessionFactory实例,每个实例对应一个数据库实例。同时,可能需要自定义...
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为开发者提供了在Java应用中操作数据库的强大工具。通过ORM,开发者可以使用面向对象的方式来处理数据,而无需直接编写SQL语句。这大大提高了开发效率并降低...
这部分可能涉及到Tiles定义、配置和如何在JSP中使用Tiles定义来组合页面。 9. **16Hibernate基本API**:这部分内容可能包括了对Hibernate核心API的介绍,如SessionFactory、Session、Query接口的使用方法,以及如何...