openSession() getCurrentSession() 区别

来源:互联网 发布:淘宝大学免费课程视频 编辑:程序博客网 时间:2024/05/21 22:28

转载自:http://hi.baidu.com/kongkongchanyi/item/c86d3c99e89e6ede7b7f018d

getHibernateTemplate().getSessionFactory().openSession()

getHibernateTemplate().getSessionFactory().getCurrentSession()

getCurrentSession ()   使用当前的session

openSession()         重新建立一个新的session 

-------------------------

SessionFactory.getCurrentSession() 是Hibernate 应用获取Session 的常用方法。在调用该方法时,Hibernate 会从interface CurrentSessionContext 获取当前的Session,这是Hibernate 在不同组件中传递Session 的方法。

CurrentSessionContext 有三个实现,分别是ThreadLocalSessionContext、JTASessionContext 和ManagedSessionContext。

ThreadLocalSessionContext 将Session 与当前线程绑定,是使用较多的一种方案;

JTASessionContext 将Session 与JTA 事务绑定,在JTA 环境中使用;

ManagedSessionContext 使应用可以通过bind() 和unbind() 方法控制Session 的绑定,主要在有Conversation 的应用中使用(如果使用ManagedSessionContext,开发人员要做的事情还是很多的)。

CurrentSessionContext 实现的选择可以通过hibernate.current_session_context_class 来配置。

另一种更常见的创建Session 的方法是openSession()。

openSession() 与getCurrentSession() 有何不同和关联呢?

在SessionFactory 启动的时候,Hibernate 会根据配置创建相应的CurrentSessionContext,在getCurrentSession() 被调用的时候,实际被执行的方法是CurrentSessionContext.currentSession() 。在currentSession() 执行时,如果当前Session 为空,currentSession 会调用SessionFactory 的openSession。所以getCurrentSession() 对于Java EE 来说是更好的获取Session 的方法。

再说ManagedSessionContext,它提供了更灵活的绑定Session 的方式,但是使用起来去不简单。

在Hibernate 的CaveatEmptor 实例中有关于使用ManagedSessionContext 的例子,但更好的选择是使用Seam Framework。

你这个是hibernate与spring整合开发,让DAO继承了spring的HibernateDaoSupport,这样的确能够提高开发效率 ,但是不够灵活,而且使DAO层依赖于spring的api,增加了耦合。但是不考虑复用的话还可以。
下面一个一个的分析:

this.getsession实际上是调用了父类中的方法获得session。使用spring管理hibernate的SessionFactory的时候,这个方法会从session池中拿出一session.这样做有可能有问题,就是超session池连接数的时候,spring无法自动的关闭session。 不推荐使用


this.getHibernateTemplate().getSessionFactory().getCurrentSession()从spring管理的sessionFactory中创建一个绑定线程的session.spring会根据该线程的执行情况来自动判断是关闭session还是延迟关闭。这样做可以避免手动的管理实务,同时一个线程最多开启和关闭一次session又可以提高程序的性能。 极力推荐使用这种方法 


this.getHibernateTemplate().getSessionFactory().OpenSession。这种方法从spring管理的sessionFactory中创建一个session,此session不是线程绑定的。当执行完一个实务的时候自动关闭session.这种方法不用手动管理实务,但是同一个线程多次的开启和关闭session,浪费系统资源和影响执行效率,正常情况下还是不要用了。 


楼主 你就不能自己动手做一下试验啊。算了 哥给你代劳吧。
这里我们讨论者三个session的关闭问题。
本来发截图了 但是百度审核啊审核 郁闷

这个是测试的dao层 log是在servi层构造好的然后传入,都学到spring了也没必要把所有代码都贴出来才能看懂吧

package com.test.spring.dao;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.test.spring.model.Log;

public class LogDaoMysqlImpl extends HibernateDaoSupport implements LogDao {

public void addLog(Log log) {
//this.getSession().save(log);
//getHibernateTemplate().save(log);
this.getHibernateTemplate().getSessionFactory().openSession().save(log);

}

}

执行结果如下,log4j产生的日志被忽略 

org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addUser)
check security
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addUser)
check security
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addLog)
check security
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addLog)
check security
Hibernate: insert into log (type, time) values (?, ?)
Sat Jan 12 00:10:00 CST 2002

没有进行session的关闭(不用spring也不用关闭session,session的关闭交给SessionFactory自动处理,但是使用spring的this.getSession没有使用spring创建SessionFactory而是直接从spring的session缓冲池拿到session,spring的session缓冲池中一般默认生成10session,前面也说了,可能是其他线程使用完没有关闭的,所以要显示的调用close,释放资源,因为取出来就放不回去了。所以要手动关闭,而且他两种获取的方法使用了spring提供的SessionFactory,spring会自动的处理没有必要进行手动关闭),就连事物的开启与关闭也不用。
这就是使用spring的好处,把切面上零散的代买同意进行处理。
楼主以后再有什么不明白的,大可以自己动手试试,不然容易把我们的错误观点变成你的。试个八百十次 自己就什么都明白了,而且比别人说的印象更加深刻。


原创粉丝点击