1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会。

2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭(调用session的close()方法)

SessionFactory.getCurrentSessionopenSession的区别
    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的好处,把切面上零散的代买同意进行处理。
楼主以后再有什么不明白的,大可以自己动手试试,不然容易把我们的错误观点变成你的。试个八百十次 自己就什么都明白了,而且比别人说的印象更加深刻。



posted on 2012-08-06 14:14  Death_Fat  阅读(296)  评论(0)    收藏  举报