SessionFactory.getCurrentSession与openSession的区别
1. 如果使用的是getCurrentSession来创建session的话,在commit后,session就自动被关闭了,
也就是不用再session.close()了。但是如果使用的是openSession方法创建的session的话,
那么必须显示的关闭session,也就是调用session.close()方法。这样commit后,session并没有关闭
2. getCurrentSession的使用可以参见hibernate\hibernate-3.2\doc\tutorial\src项目
3. 使用SessionFactory.getCurrentSession()需要在hibernate.cfg.xml中如下配置:
* 如果采用jdbc独立引用程序配置如下:
<property name="hibernate.current_session_context_class">thread</property>
* 如果采用了JTA事务配置如下
<property name="hibernate.current_session_context_class">jta</property>
利于ThreadLocal模式管理Session
早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序
时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,
而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)
其实的功用非常简单,就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,
而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,
用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型):
public class HibernateUtil {
public static final ThreadLocal session =new ThreadLocal();
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}
区别(转载)
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,浪费系统资源和影响执行效率,正常情况下还是不要用了。
这个是测试的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的好处,把切面上零散的代买同意进行处理。
楼主以后再有什么不明白的,大可以自己动手试试,不然容易把我们的错误观点变成你的。试个八百十次 自己就什么都明白了,而且比别人说的印象更加深刻。
浙公网安备 33010602011771号