一、缘由
上一篇文章Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法介绍到了怎么样在Sping、MyBatis、Hibernate整合的应用中动态切换DataSource数据源的方法,但最终遗留下一个问题:不能切换数据库方言。数据库方言可能在当前应用的架构中意义不是很大,但是如果单纯用MyBatis或Hibernate做数据库持久化操作,还是要处理这一问题。
那么下面将介绍怎么样动态切换SessionFactory,为什么要切换SessionFactory?
因为这里切换SessionFactory就可以实现多数据源和多个SessionFactory,每个SessionFactory有自己独立的数据库配置和SessionFactory的相关配置。我们的数据库方言就配置在SessionFactory这里,所以实现了切换SessionFactory也就实现了切换数据库方言的问题。这个主要是针对Hibernate来操作的,而MyBatis则需要动态切换SqlSessionFactory才行。
二、实现代码
1、定义全局切换SessionFactory的工具
package com.hoo.framework.spring.support;
/**
* <b>function:</b> 多数据源
* @author hoojo
* @createDate 2013-9-27 上午11:36:57
* @file CustomerContextHolder.java
* @package com.hoo.framework.spring.support
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public abstract class CustomerContextHolder {
public final static String SESSION_FACTORY_MYSQL = "mysql";
public final static String SESSION_FACTORY_ORACLE = "oracle";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
同样上面的静态变量和前一文章中介绍的一致,它需要和下面配置文件中的SessionFactory的key对应。
2、实现自己的SessionFactory
定义好接口
package com.hoo.framework.spring.support.core;
import org.hibernate.SessionFactory;
/**
* <b>function:</b> 动态SessionFactory接口
* @author hoojo
* @createDate 2013-10-12 下午03:29:52
* @file DynamicSessionFactory.java
* @package com.hoo.framework.spring.support.core
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public inte易做图ce DynamicSessionFactory extends SessionFactory {
public SessionFactory getHibernateSessionFactory();
}
实现接口
package com.hoo.framework.spring.support.core;
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.hibernate.Cache;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.TypeHelper;
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 com.hoo.framework.spring.support.CustomerContextHolder;
/**
* <b>function:</b> 动态数据源实现
* @author hoojo
* @createDate 2013-10-12 下午03:31:31
* @file DynamicSessionFactoryImpl.java
* @package com.hoo.framework.spring.support.core
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@SuppressWarnings({ "unchecked", "deprecation" })
public class DynamicSessionFactoryImpl implements DynamicSessionFactory {
private static final long serialVersionUID = 5384069312247414885L;
private Map<Object, SessionFactory> targetSessionFactorys;
private SessionFactory defaultTargetSessionFactory;
/**
* @see com.hoo.framework.spring.support.core.DynamicSessionFactory#getHibernateSessionFactory()
* <b>function:</b> 重写这个方法,这里最关键
* @author hoojo
* @createDate 2013-10-18 上午10:45:25
*/
@Override
public SessionFactory getHibernateSessionFactory() {
SessionFactory targetSessionFactory = targetSessionFactorys.get(CustomerContextHolder.getCustomerType());
if (targetSessionFactory != null) {
return targetSessionFactory;
} else if (defaultTargetSessionFactory != null) {
return defaultTargetSessionFactory;
}
return null;
}
@Override
public void close() throws HibernateException {
this.getHibernateSessionFactory().close();
}
@Override
public boolean containsFetchProfileDefinition(String s) {
return this.getHibernateSessionFactory().containsFetchProfileDefinition(s);
}
@Override
public void evict(Class clazz) throws HibernateException {
this.getHibernateSessionFactory().evict(clazz);
}
@Override
public void evict(Class clazz, Serializable serializable) throws HibernateException {
this.getHibernateSessionFactory().evict(clazz, serializable);
}
@Override
public void evictCollection(String s) throws HibernateException {
this.getHibernateSessionFactory().evictCollection(s);
}
@Override
public void evictCollection(String s, Se
补充:软件开发 , Java ,