熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

利用ThreadLocal綁定Hibernate的session

2013-11-23 20:40:57  來源: Java開源技術 

  無論是立即加載還是延遲加載必須要連接數據庫的而在java中連接數據庫是依賴javasqlConnection在hibernate中session就是Connection的一層高級封裝一個session對應了一個Connection要實現延遲加載必須有session才行而且要進行延遲加載還必須保證是同一個session才行用另外一個session去延遲加載前一個session的代理對象是不行的大家都知道Connection是使用過後必須要進行關閉的那麼我們如何保證一次http請求過程中一直都使用一個session呢即一個Connection呢而且還要保證http請求結束後正確的關閉

  好現在我們知道了我們要解決的問題

  如何保證http請求結束後正確的關閉session

  如何保證http請求過程中一直使用同一個session

  第一個問題很容易想到使用過濾器

  view plaincopy to clipboardprint?
    public void doFilter(ServletRequest request ServletResponse response

  FilterChain filterChain) {

  try {

  filterChaindoFilter(request response);

  } catch (IOException e) {

  eprintStackTrace();

  } catch (ServletException e) {

  eprintStackTrace();

  } finally {

  try {

  mitTransaction();

  } catch (Exception e) {

  HibernateUtilrollbackTransaction();

  } finally {

  HibernateUtilcloseSession();

  }

  }

  }

  public void doFilter(ServletRequest request ServletResponse response

  FilterChain filterChain) {

  try {

  filterChaindoFilter(request response);

  } catch (IOException e) {

  eprintStackTrace();

  } catch (ServletException e) {

  eprintStackTrace();

  } finally {

  try {

  mitTransaction();

  } catch (Exception e) {

  HibernateUtilrollbackTransaction();

  } finally {

  HibernateUtilcloseSession();

  }

  }

  }要解決第二個問題我們必須先搞清楚http請求在java中是以什麼樣的機制實現的在java中一個請求就是一個線程像流行的web容器Tomcat等往往都是采用線程池機制的也就是說有n個線程在池子裡面每當有http請求時隨機從線程池中取出一個線程對象去處理請求實際上多次請求可能使用的是同一線程也可能不是這是隨機的要保證整個請求中使用同一session最容易想到的就是把這個session綁定到線程上在java中使用ThreadLocal可以輕松綁定變量每個線程有一個自己的ThreadLocal這個ThreadLocal會隨線程的銷毀一起銷毀既然是每個線程有一個那麼多個線程間自然是不會有影響了所以把session綁定在ThreadLocal裡面是最好的選擇了

  有關ThreadLocal的更多資料大家可以百度或者參考

  

  

  最後我把相關的代碼發出來

  view plaincopy to clipboardprint?
    import javasqlSQLException;

  import orghibernateHibernateException;

  import orghibernateSession;

  import orghibernateSessionFactory;

  import orghibernateTransaction;

  import orghibernatecfgConfiguration;

  import javasqlConnection;

  import orgapachelogjLogger;

  import javaioFile;

  /**

  *

  * <p>

  * Title:Hibernate工具類

  * </p>

  *

  * <p>

  * 利用ThreadLocal 綁定 Hibernate 的session

  * </p>

  *

  * @author 孫钰佳

  * @mail

  * @version

  */

  public class HibernateUtil {

  /**

  * Logerj的logger

  */

  private static final Logger logger = LoggergetLogger(HibernateUtilclass);

  /**

  * 存儲hibernate session的ThreadLocal

  */

  private static final ThreadLocal sessionThread = new ThreadLocal();

  /**

  * 存儲事務的ThreadLocal

  */

  private static final ThreadLocal transactionThread = new ThreadLocal();

  /**

  * Hibernate 的 Session工廠

  */

  private static SessionFactory sessionFactory = null;

  /**

  * 初始化SessionFactory

  *

  * @param file

  *            Hibernate配置文件

  */

  public static void initSessionFactory(File file) {

  Configuration config = new Configuration();

  nfigure(file);

  sessionFactory = configbuildSessionFactory();

  }

  /**

  * 獲取當前線程綁定的session

  *

  * @return Session

  * @throws HibernateException

  */

  public static Session getSession() {

  Session s = (Session) sessionThreadget();

  if (s == null) {

  s = sessionFactoryopenSession();

  sessionThreadset(s);

  } else {

  Connection conn = nnection();

  try {

  if (conn == null || connisClosed()) {

  try {

  sclose();

  } catch (HibernateException e) {

  loggerwarn(close session error: + egetMessage() e);

  }

  s = sessionFactoryopenSession();

  sessionThreadset(s);

  }

  } catch (SQLException e) {

  throw new HibernateException(e);

  }

  }

  return s;

  }

  /**

  * 取得當前session的事務

  *

  * @return Transaction

  */

  public static Transaction transaction() {

  Transaction transaction = (Transaction) transactionThreadget();

  if (transaction == null) {

  transaction = getSession()beginTransaction();

  transactionThreadset(transaction);

  }

  return transaction;

  }

  /**

  * 提交當前session的事務

  */

  public static void commitTransaction() {

  Transaction transaction = (Transaction) transactionThreadget();

  transactionThreadset(null);

  if (transaction != null)

  mit();

  }

  /**

  * 回滾當前session的事務

  */

  public static void rollbackTransaction() {

  Transaction tx = (Transaction) transactionThreadget();

  transactionThreadset(null);

  if (tx != null)

  txrollback();

  }

  /**

  * 關閉當前線程使用的session

  */

  public static void closeSession() {

  Session session = (Session) sessionThreadget();

  if (session != null) {

  sessionclear();

  sessionclose();

  sessionThreadset(null);

  }

  }

  }

  import javasqlSQLException;

  import orghibernateHibernateException;

  import orghibernateSession;

  import orghibernateSessionFactory;

  import orghibernateTransaction;

  import orghibernatecfgConfiguration;

  import javasqlConnection;

  import orgapachelogjLogger;

  import javaioFile;

  /**

  *

  * <p>

  * Title:Hibernate工具類

  * </p>

  *

  * <p>

  * 利用ThreadLocal 綁定 Hibernate 的session

  * </p>

  *

  * @author 孫钰佳

  * @mail

  * @version

  */

  public class HibernateUtil {

  /**

  * Logerj的logger

  */

  private static final Logger logger = LoggergetLogger(HibernateUtilclass);

  /**

  * 存儲hibernate session的ThreadLocal

  */

  private static final ThreadLocal sessionThread = new ThreadLocal();

  /**

  * 存儲事務的ThreadLocal

  */

  private static final ThreadLocal transactionThread = new ThreadLocal();

  /**

  * Hibernate 的 Session工廠

  */

  private static SessionFactory sessionFactory = null;

  /**

  * 初始化SessionFactory

  *

  * @param file

  *            Hibernate配置文件

  */

  public static void initSessionFactory(File file) {

  Configuration config = new Configuration();

  nfigure(file);

  sessionFactory = configbuildSessionFactory();

  }

  /**

  * 獲取當前線程綁定的session

  *

  * @return Session

  * @throws HibernateException

  */

  public static Session getSession() {

  Session s = (Session) sessionThreadget();

  if (s == null) {

  s = sessionFactoryopenSession();

  sessionThreadset(s);

  } else {

  Connection conn = nnection();

  try {

  if (conn == null || connisClosed()) {

  try {

  sclose();

  } catch (HibernateException e) {

  loggerwarn(close session error: + egetMessage() e);

  }

  s = sessionFactoryopenSession();

  sessionThreadset(s);

  }

  } catch (SQLException e) {

  throw new HibernateException(e);

  }

  }

  return s;

  }

  /**

  * 取得當前session的事務

  *

  * @return Transaction

  */

  public static Transaction transaction() {

  Transaction transaction = (Transaction) transactionThreadget();

  if (transaction == null) {

  transaction = getSession()beginTransaction();

  transactionThreadset(transaction);

  }

  return transaction;

  }

  /**

  * 提交當前session的事務

  */

  public static void commitTransaction() {

  Transaction transaction = (Transaction) transactionThreadget();

  transactionThreadset(null);

  if (transaction != null)

  mit();

  }

  /**

  * 回滾當前session的事務

  */

  public static void rollbackTransaction() {

  Transaction tx = (Transaction) transactionThreadget();

  transactionThreadset(null);

  if (tx != null)

  txrollback();

  }

  /**

  * 關閉當前線程使用的session

  */

  public static void closeSession() {

  Session session = (Session) sessionThreadget();

  if (session != null) {

  sessionclear();

  sessionclose();

  sessionThreadset(null);

  }

  }

  }

  下面是一個調用的例子: view plaincopy to clipboardprint?
    public static void main(String[] args) throws Exception {

  HibernateUtilinitSessionFactory(new File(TestclassgetClassLoader()

  getResource(hibernatecfgxml)getFile()));

  Session session = HibernateUtilgetSession();

  HibernateUtiltransaction();

  User u = new User();

  usetName(test);

  sessionsave(u);

  mitTransaction();

  HibernateUtilcloseSession();

  }


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28894.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.