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

来源:互联网 发布:阿苏拉男捏脸数据 编辑:程序博客网 时间:2024/06/06 01:56

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,那么我们可以这样实现:

@BeforeClasspublic static void beforeClass() throws Exception {HibernateUtil.currentSession().beginTransaction();}@AfterClasspublic static void afterClass() throws Exception {HibernateUtil.currentSession().getTransaction().commit();HibernateUtil.closeCurrentSession();}


 

 

原创粉丝点击