zoukankan      html  css  js  c++  java
  • Hibernate中openSession()与getCurrentSession()的区别与联系

    SessionFactory接口获得Session(会话)实例有两种方式,一种是通过openSession(),另外一种是通过getCurrentSession()。这里讨论获得Session两种方式的区别与联系。

    一、区别

    1、openSession() 是获取一个新的session;而getCurrentSession() 是获取和当前线程绑定的session,换言之,在同一个线程中,我们获取的session是同一个session,这样可以利于事务控制。

    SessionFactory sessionfactory = MySessionFactory.getSessionFactory();
    		
    		Session  session1 = sessionfactory.openSession();
    		Session  session2 = sessionfactory.openSession();
    
    		Session  session3 = sessionfactory.getCurrentSession();
    		Session  session4 = sessionfactory.getCurrentSession();
    		
    		System.out.println("openSession:      "+session1.hashCode()+"  "+session2.hashCode());
    		System.out.println("getCUrrentSession:"+session3.hashCode()+"  "+session4.hashCode());
    

     输出结果为:

    openSession:         3300884  30323167
    getCUrrentSession:30005474  30005474

    可见openSession()获取的Session是不同的,而getCUrrentSession()获取的是同一个Session。

    在开发中如何选择openSession()和 getCurrentSession():

    • 如果需要在同一线程中,保证使用同一个Session则,使用getCurrentSession()
    • 如果在一个线程中,需要使用不同的Session,则使用opentSession()

    2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:

     如果使用的是本地事务(jdbc事务)

    <property name="hibernate.current_session_context_class">thread</property> 
    

    如果使用的是全局事务(jta事务)

    <property name="hibernate.current_session_context_class">jta</property> 
    

     3、通过 getCurrentSession() 获取的session在commit或rollback时会自动关闭;通过openSession()获取的session则必须手动关闭。

     4、通过getCurrentSession() 获取sesssion进行查询需要事务提交;而通过openSession()进行查询时可以不用事务提交。

    二、联系

    在 SessionFactory启动的时候,Hibernate 会根据配置创建相应的 CurrentSessionContext,在getCurrentSession()被调用的时候,实际被执行的方法是CurrentSessionContext.currentSession()。在currentSession()执行时,如果当前Session为空,currentSession会调用SessionFactory的openSession。

    上面这句话很绕,这里通过一个例子来说明openSession()和getCurrentSession()的联系:用openSession()通过ThreadLocal模式 (线程局部变量模式)生成getCurrentSession()

    注:所谓线程局部变量模式,就是让一个变量与线程绑定

    package com.chongqing.utils;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class HibernateUtil {
    	
    	private static SessionFactory sessionFactory = null;
    	
    	private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    	
    	private HibernateUtil() {
    		
    	}
    	
    	static {
    		
    		sessionFactory = new Configuration().configure().buildSessionFactory();	
    	}
    	
    	//获取全新的Session
    	public static Session openSession() {
    		return sessionFactory.openSession();
    	}
    	
    	//获取与线程绑定的Session
    	public static Session getCurrentSession() {
    		Session session = threadLocal.get();
    		
    		//如果没有得到Session。则通过ThreadLocal将openSession与线程绑定
    		if(null == session){		
    			session = sessionFactory.openSession();
    			threadLocal.set(session);					
    		}
    		
    		return session;
    		
    	}
    
    }
    
  • 相关阅读:
    windows系统调用 互斥体mutex
    windows系统调用 利用事件对象实现进程通信
    windows系统调用 调度优先级
    <十四>JDBC_c3p0数据库连接池
    <十三>JDBC_dbcp数据库连接池
    <十二>JDBC_批量处理
    <十一>JDBC_事务的处理+隔离
    <十>JDBC_处理Blob类型数据
    <八>JDBC_重构DAO查询方法
    <七>JDBC_使用beanutils工具类操作javaBean
  • 原文地址:https://www.cnblogs.com/yzy-blogs/p/6742753.html
Copyright © 2011-2022 走看看