HibernateUtil详解

\首先,我们先来看一段代码,传统的Hibernate获得Session进行CRUD的操作:
// 1.创建Configuration引用
		Configuration configuration = new Configuration();
		// 2.创建SessionFactory,SessionFactory是一个重量级对象,所谓重量级对象会很吃计算机的内存,因为该对象要完成对映射文件的管理,
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.获得Session
		Session session = sessionFactory.openSession();
		Transaction ts = session.beginTransaction();
		/*
		 * 此处省略CRUD操作代码
		 */
		// 4.事务提交
		ts.commit();
		// 5.关闭连接
		session.close();


 

 

正如代码中说的,SessionFactory是一个吃内存的对象,一个项目如果针对一个数据库最好将SessionFactory对象做成单例模式即可.像以上的代码不仅冗余的代码很多,而且使用起来每次打开一个新的Session对于多个页面之间的事务处理是十分不方便的,比如说你的WEB项目有两个控制器(controller),分别命名为A和B,在A页面进行进行转账业务,在B页面进行获取账户余额,这两个应该是放在一个事务里面处理,但是由于A页面和B页面都需要进行openSession()而这个方法返回的Session不是同一个(打印HashCode())对象,所以不方便进行多个页面的事务处理,现在我们就有这样的一个需求,多个页面使用一个Session对象,这个需求要怎么实现那?

 

我们可以把Session放在一个线程局部变量中(ThreadLocal),在同一个执行路径里面这个变量可以一直被调用,而且获得的都是同一个变量

 

ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();//通过泛型指定存储的是什么类型的变量
threadLocal.set(Session session);//设置Session
Session session = threadLocal.get();//获得Session

 

下面开始HibernateUtil的封装:

 


 

package com.wsl.util;

import org.hibernate.*;
import org.hibernate.cfg.*;

/**
 * 
 * @author 小吴同学
 * 
 */

public class HibernateUtil {
	// SessionFactory会话工厂
	private static SessionFactory sessionFactory = null;
	// 线程局部变量管理
	private static ThreadLocal
  
  
   
    threadLocal = new ThreadLocal
   
   
    
    ();

	// 写在static块是因为该块只会被类被ClassLoader加载到虚拟机的时候执行一次
	static {
		try {
			// 使用Configuration()对象.configure()方法去读取src/hibernate.cfg.xml配置文件
			sessionFactory = new Configuration().configure()
					.buildSessionFactory();// 产生一个SessionFactory
		} catch (Throwable e) {// 如果在执行static块的时候出现任何的Throwable(Error和Exception的类的父类)则处理
			// 抛出明确的static程式错误的异常
			throw new ExceptionInInitializerError(e);
		}
	}

	/**
	 * 
	 * 获得SessionFactory这个就不说了
	 * 
	 * @return SessionFactory
	 */
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
	 * 获得Session会话对象
	 * 
	 * @return Session
	 */

	public static Session getSession() {
		// 首先从线程局部变量中有没有session,以免还要openSession();
		Session session = threadLocal.get();
		// 如果是空或者没有打开
		if (session == null || !session.isOpen()) {
			// 则打开(因为static块有可能出错,所以这里进行三元判断)
			session = sessionFactory != null ? sessionFactory.openSession()
					: null;
			// 设置到线程局部变量中
			threadLocal.set(session);
		}
		return session;
	}

	// 关闭Session
	public static void closeSession() {
		// 获得线程局部变量中的session
		Session session = threadLocal.get();
		// 设置为空,当再次调用openSession()的时候才能打开Session
		threadLocal.set(null);
		if (session != null) {
			session.close();
		}
	}
}

   
   
  
  


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值