Hibernate学习总结(4)——session管理

6.Session管理

Java程序的运行起点要么是主线程,要么是主线程中启动的新线程。主方法(线程run方法)既是起点,也是终点,其它方法被上一层调用,也调用下一层,等待下一层返回,最终也会返回给上一层。

在每一次的调用中开始和结束都要开闭Session,频繁开闭Session不仅造成性能的浪费,上一层调用者获得下一层方法返回的实体对象(关联的session关闭后可能是游离态)仍然无法延迟加载,让延迟加载成了鸡肋 。

那么我们可以对Session进行管理,是Session成为在线程内可共享的Session,在整个线程中每次方法调用获得开启共享的Session实例,在线程结束时关闭Session。这样既减少了性能浪费,代码重复,有解决了一些在线程中延迟加载的问题。代码如下:

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
//产生SessionFactory实例
public class HibernateUtil {
	private static SessionFactory sessionFactory;// 静态变量
	//这相当于一个容器,从里面取出的变量是当前线程中变量的副本
	public static final ThreadLocal<Session> HIBERNATE_SESSION_LOCAL =  new ThreadLocal<Session>();   
	
	static {// 静态初始化块
		try {
			Configuration cfg = new Configuration().configure("/cfg/hibernate.xml");
			// Hibernate4提供的新方式
			ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
					.applySettings(cfg.getProperties()).buildServiceRegistry();
			sessionFactory = cfg.buildSessionFactory(serviceRegistry);
		} catch (Throwable ex) {
			throw new ExceptionInInitializerError(ex);
		}
	}
	/**
	 * 获取线程内共享的Session实例
	 * @return
	 */
	public Session currentSession(){
		Session session = HIBERNATE_SESSION_LOCAL.get();//取出本地变量
		if(session == null){//如果没有
			session = getSession();//新建Session实例
			HIBERNATE_SESSION_LOCAL.set(session);//存放本地变量
		}
		return session;
	}
	/**
	 * 关闭线程内共享的Session实例
	 */
	public void closeCurrentSession(){
		try {
			currentSession().close();
		} catch (Exception e) {
//			e.printStackTrace();
		}
	}
	
	/**
	 * 开启一个新的Session
	 * @return
	 */
	public Session getSession(){
		return sessionFactory.openSession();
	}
	
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	public static void shutdown() {
		getSessionFactory().close();
	}

	
}


我们可以在一下情况关闭Session:

(1)Junit测试中可以在测试方法结束后关闭;
(2)CS结构中可在线程结束时关闭;
(3)BS-web结构中,可在一次请求结束后关闭。

在Junit测试是一个线程可以依次执行多个方法,所以我们需要在所有方法调用前开启事务,在所有方法完成后再提交事务并关闭Session,那么我们可以这样实现:

@BeforeClass
public static void beforeClass() throws Exception {
HibernateUtil.currentSession().beginTransaction();
}
@AfterClass
public static void afterClass() throws Exception {
HibernateUtil.currentSession().getTransaction().commit();
HibernateUtil.closeCurrentSession();
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值