hibernate中建立session的兩種方式方式,區別在哪裡?

南夏發表於2015-12-13
 

hibernate的session的產生方式,區別在哪裡?

hibernate的session的產生方式,區別在哪裡?如何產生?

session的產生方式有哪些,並且為什麼要分這個?

產生流程:



1、方式一

sessionFactory.opensession():一般的crud操作我們用的是這個操作,只有增刪改才用到事務,查詢不需要。

  1. //  session的第一種產生方式:opensession():每一次都產生一個新物件  
  2.     @Test  
  3.     public void sessio_opensession(){  
  4.         Session session=sessionfactory.openSession();  
  5.         Transaction transaction=session.beginTransaction();  
  6.         transaction.commit();  
  7.         session.close();  
  8.     }  

2.方式二

sessionFactory.getCurrentSession():這個方式用的理由如下;

理由:如果有多個擁有session的方法互相呼叫,這個時候就存在多個session物件和多個事務了。保證不了crud操作只在一個session物件和事務中操作?這個時候寄引用到第二種方式了。

  1. //  session的第二種產生方式:getCurrentSession():  
  2. //  每次都要在localThread中判斷是否有這個物件,有的話直接拿出來用。  
  3. //  沒有的話,新建一個,與Factory繫結放入LocalThread中。  
  4. //  這種方式下的crud操作,全都必須在事務下操作,(並且事務和session是繫結在一起的。)  
  5.     @Test  
  6.     public void sessionfac_crate(){  
  7.         Session session=sessionfactory.getCurrentSession();  
  8.         Transaction transaction=session.beginTransaction();  
  9.         session.load(Classes.class, 1L);  
  10.         transaction.commit();  
  11. //      session.close();//事務已提交就自動關閉了,就不用寫這個關閉了。不然就會出連線已關閉的錯  
  12.     }  

sessionFactory.getCurrySession為什麼這種方式下的事務會和session繫結在一起?理由?這個問題在網上的爭議都挺大的。沒有準確的答案

總結了兩點:

session.getCurrentSession的用法

  1、在hibernate的配置檔案中必須加上這個才能用第二種方式:

        <propertyname="current_session_context_class">thread</property>

  2、不需要寫session.close方法,在事務提交的時候會自動關閉(hibernate內部完成)

  3crud都需要事務

      1、因為是一個執行緒,所以在整個方法中有一個session和一個事務

      2、保證了整個業務操作的安全性


網上針對事務為什麼繫結在一起的說法:

getCurrentSession得到的session是和事務繫結的session,所以:
1,要用getCurrentSession生產的session,就必須有事務環境,意思就是你必須在呼叫session方法之前,session.beginTransaction();就算你只是get或者query


2,在事務提交之後,即session.getTransaction().commit()之後,session自動關閉,所以你用getCurrentSession,只需要commit事務,不要去呼叫session.close()。

3,你用的是ssh,spring為hibernate的current_session_context_class配置了一個SpringSessionContext來幫你管理getCurrentSession中的session,所以,你在OpenSessionInview的時候,spring就自動的幫你開啟了session——>你在執行用AOP包裝的事務的時候,事務就開啟了——>執行你的業務方法——>提交事務(注意,hibernate管理的getCurrentSession在提交事務的時候才會關閉ession,而spring提供的這個SpringSessionContext不會)——>opensessioninview關閉session。
從上面的執行流程可以看出,你在SSH整合的時候,如果用的是getCurrentSession的整合方式,就不能設定hibernate的current_session_context_class為thread,而應該空著,讓spring幫你。


相關文章