Hibernate中SessionFactory的单例模式

(1)单例模式的引入

由于本系统采用的是hibernate框架,hibernate强制要求使用事务,在进行增删查改等操作时必须要求先开启事务。如果不开启事务的话,那么事务就会默认是失败的,也即是会一直处于回滚的状态,所以不开启事务每一次的操都是不成功的。
如下图所示,关闭事务之后,查询图书时就会出现没有**事务的异常信息。
Hibernate中SessionFactory的单例模式
所以这就要求我们必须在进行操作之前先开启事务。而事务又是由session进行管理的,而session对象又是由SessionFactory负责创建的。那么下面重点介绍一下这个SessionFactory。

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。Session session = sessionFactory.openSession();。需要注意的是SessionFactory并不是轻量级的,构造SessionFactory很消耗资源(SesionFactory管理着一个进程级的缓存),一般情况下一个应用中只初始化一个 SessionFactory对象,一个SessionFactory对应一个数据源。所以一个项目通常只需要一个SessionFactory就够了,这个工程所涉及到的所有的session,都交由这个sessionfactory来管理。由于我这个系统也没有正式上线,所以也不存在数据量过大的问题,所以也就只有一个数据库。因此我的这个工程中只需要一个SessionFactory就好了,既然只需要一个实例,那毫无疑问的可以使用单例模式来处理这个问题了。单例模式分为饿汉式和懒汉式,那到底选用哪一种呢?懒汉式在多线程使用时会有线程安全的问题,饿汉式每次都会创建新的对象不会出现线程安全的问题,但是每次都要创建新的对象这就会导致每次都要重新初始化分配内存这样效率没有那么好了。打开sessionFactory的源码我们可以发现它的变量都是使用final修饰的,所以SessionFactory是线程安全的(允许多线程共享使用)。所以这里我可以使用单例模式的懒汉式。

SessionFactory源码截图:
Hibernate中SessionFactory的单例模式

(2)单例模式的实现

package xaut.wjh.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
/**
 * 单例模式的懒汉式:sessionFactory==null时才进行创建对象
 * 
 * @author 17976
 *
 */
public class HibernateSessionFactory {

	private static volatile  SessionFactory sessionFactory;

	static {
		buildSessionFactory();
	}
	private  HibernateSessionFactory() {

	}
	
	public static Session currentSession() {
		return sessionFactory.getCurrentSession();
	}
	
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public static void setSessionFactory(SessionFactory sessionFactory) {
		HibernateSessionFactory.sessionFactory = sessionFactory;
	}

	private static void buildSessionFactory() {
		if(sessionFactory==null) {
			Final StandardServiceRegistry ssr=new StandardServiceRegistryBuilder().configure().build();
			sessionFactory=new MetadataSources(ssr).buildMetadata().buildSessionFactory();
		}
	}	
}

我的设计模式课设的部分内容。