Session接口是Hibernate應用使用最普遍的接口,Session也被稱爲持久化管理器。Session對象是Hibernate技術的核心,持久化化對象的生命週期、事務的管理和持久化對象的查詢、更新和刪除都是經過Session對象來完成的。java
Session接口是一個非線程安全的,避免多個線程共享一個Session實例。Session對象經過SessionFactory對象的getCurrentSession()或者openSession()方法獲取,示例代碼以下:數據庫
Session session = sessionFactory.openSession(); Session session = sessionFactory.getCurrentSession();
Session對象獲取後,不會馬上獲取Connection對象,而是在Session對象須要對數據庫進行操做時纔會從數據庫鏈接池中獲取Connection對象。而關閉Session對象時,不會直接關閉Connection,而是將Connection對象返回到鏈接池中。設計模式
在Hibernate 3.1版本以後,能夠經過在hibernate.cfg.xml文件中配置如下內容:緩存
<property name="current_session_context_class">thread</property>
配置後代表Hibernate使用ThreadLocal對象來管理Session對象,ThreadLocal對象應用了Thread-Specific Storage設計模式。這種模式能夠有效隔離線程所使用的數據,因此避開了Session對象在多線程狀況下的數據共享問題。使用這個配置信息以後,Session對象只能經過SessionFactory對象的getCurrentSession()方法獲取。安全
早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal爲解決多線程程序的併發問題提供了一種新的思路。使用這個工具類能夠很簡潔地編寫出優美的多線程程序。session
ThreadLocal和線程同步機制同樣都是爲了解決多線程中相同變量的訪問衝突問題。多線程
在同步機制中,經過對象的鎖機制保證同一時間只有一個線程訪問變量。這時該變量是多個線程共享的,使用同步機制要求程序慎密地分析何時對變量進行讀寫,何時須要鎖定某個對象,何時釋放對象鎖等繁雜的問題,程序設計和編寫難度相對較大。併發
而ThreadLocal則從另外一個角度來解決多線程的併發訪問。ThreadLocal會爲每個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問衝突。由於每個線程都擁有本身的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,能夠把不安全的變量封裝進ThreadLocal。工具
ThreadLocal類接口以下:spa
- void set(Object value)設置當前線程的線程局部變量的值。
- public Object get()該方法返回當前線程所對應的線程局部變量。
- public void remove()將當前線程局部變量的值刪除,目的是爲了減小內存的佔用,該方法是JDK 5.0新增的方法。須要指出的是,當線程結束後,對應該線程的局部變量將自動被垃圾回收,因此顯式調用該方法清除線程的局部變量並非必須的操做,但它能夠加快內存回收的速度。
- protected Object initialValue()返回該線程局部變量的初始值,該方法是一個protected的方法,顯然是爲了讓子類覆蓋而設計。此方法是一個延遲調用方法,在線程第1次調用get()或set(Object)時才執行,而且僅執行1次。ThreadLocal中缺省實現直接返回一個null。
Java對象在hibernate持久化層的狀態:
臨時態:不被session關聯,在數據庫中沒有相應的記錄
持久態:被session關聯,在數據庫中有對應的記錄
刪除態:不被session關聯,而且session已經計劃從數據庫中刪除
遊離態:不被session關聯,在數據庫中有對應的記錄
首先根據id在session緩存(一級緩存)查詢,沒有的話查詢二級緩存,最後查詢數據庫,查不到就返回null。
此方法默認認定id對應的對象(數據庫記錄)在數據庫中是必定存在的,若是數據庫中不存在該記錄,則拋出異常。
首先根據id在session緩存(一級緩存)查詢,沒有的話查詢數據庫,查不到就拋出異常。
用來保存持久化對象,即在數據庫中新增記錄。
根據對象的狀態(臨時,持久,託管)對對象進行save或update操做。
當對象的狀態爲臨時狀態時,對對象進行save操做
當對象的狀態爲持久或託管狀態時,對對象進行update操做
使一個遊離對象轉變爲持久化對象。
Session只有在清理緩存的時候才執行update語句,而且在執行的時候纔會把對象的當前屬性封裝到update語句中,所以程序屢次修改對象的屬性,在清理緩存的時候只會執行一次update語句。
用update()關聯一個對象的時候,若緩存中已經存在了同類型而且OID相同的對象,就會報錯,應該改用merge()。
刪除遊離態對象或是持久態對象,若刪除的是遊離態對象,先將對象變爲持久態。
使用delete()方法刪除數據庫表中的一條記錄,首先要經過該對象的get()或者load()方法獲取要刪除記錄對應的持久化對象,而後經過delete()方法刪除。
將一個遊離對象的屬性複製到一個持久化對象中。其處理流程以下:
(1)根據遊離對象的id到Session緩存中查找匹配的持久化對象。若找到匹配的持久化對象,則將遊離對象的屬性複製到持久化對象中,計劃實行一條update語句,而後返回持久化對象的引用。
(2)若是在Session的緩存中沒有找到與遊離對象id一致的持久化對象,那麼就試圖根據該id從數據庫中加載持久化對象。若是數據庫中存在匹配的持久化對象,則將遊離對象的屬性複製到剛加載的持久化對象中,計劃實行一條update語句,而後返回持久化對象的引用。
(3)若是數據庫中也不存在或者對象是臨時對象時,則會新建一個對象,將屬性賦值到該新建對象中,再持久化新建對象,最後返回新建對象的引用。
merge()執行後,該對象狀態爲遊離態