1:getCurrentSession會把Session和當前的線程關聯起來,而openSession只是重新開啓一個Session
2:getCurrentSession獲得的Session會在事務關閉或者回滾時會自動關閉,而openSession獲得的Session必須手動關閉
getCurrentSession,特定的實現用它來負責跟蹤當前的上下文session,Hibernate內置了此接口的兩種實現
* org.hibernate.context.JTASessionContext --當前session通過當前執行的線程來跟蹤和界定
* org.hibernate.context.ThreadLocalSessionContext --當前線程通過當前執行的線程和跟蹤和界定
這兩種實現都提供了“每數據庫事務對應一個session”的編程模型,也稱作每次請求一個session,Hibernate session的起始和終結由數據庫事務的生存來控制。
3:關於ThreadLocal的理解
線程局部變量,就是爲每一個使用某變量的線程都提供一個該變量值的副本,是每一個線程都可以獨立的改變自己的副本,而不會和其他線程的副本衝突,從線程的
角度看就好像每一個線程都完全擁有一個變量
實例代碼:
- package com.capinfotech.ju.util;
- import org.hibernate.HibernateException;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- public class HibernateUtil {
- public static final ThreadLocal sessionThreadLoacl = new ThreadLocal();
- public static final SessionFactory sessionFactory;
- static {
- try {
- sessionFactory = new Configuration().configure().buildSessionFactory();
- } catch(Throwable t) {
- throw new ExceptionInInitializerError(t);
- }
- }
- /**
- * 獲取當前的Session
- * @return
- * @throws HibernateException
- */
- public static Session currentSession() throws HibernateException {
- Session session = (Session) sessionThreadLoacl.get();
- if(session == null) {
- session = sessionFactory.openSession();
- sessionThreadLoacl.set(session);
- }
- return session;
- }
- /**
- * 釋放Session
- * @throws HibernateException
- */
- public static void closeSession() throws HibernateException {
- Session session = (Session)sessionThreadLoacl.get();
- if(session != null) {
- session.close();
- }
- sessionThreadLoacl.set(null);
- }
- }
在sessionFactory啓動的時候,Hibernate會根據配置創建相應的CurrentSessionContext,在getCurrentSession()被調用的時候,實際被執行的方法是CurrentSessionContext.currentSession(),在currentSession()執行時,如果當前Session爲空,currentSession會調用SessionFactory的openSession,
這樣既保證了Session的線程安全,又不用每次數據庫操作都重新獲取一個Session實例,實現了Session重用