演示對象的生命週期及Session接口
一、hibernate中對象根據其狀態可以劃分如下:
1、 瞬時對象(Transient Objects,臨時對象):使用new 語句創建,還沒有被持久化,不處於Session的緩存中。也就是說它們沒有任何跟數據庫表相關聯的行爲,只要應用不再引用這些對象,它們的狀態將會丟失,並由垃圾回收機制回收。
2、 持久化對象(Persistent Objects):已經被持久化,加入到Session緩存中。持久實例是任何具有數據庫標識的實例,它由持久化管理器Session統一管理,持久實例是在事務中進行操作的——它們的狀態在事務結束時同數據庫進行同步。當事務提交時,通過執行SQL的INSERT、UPDATE和DELETE語句把內存中的狀態同步到數據庫中。
3、 遊離對象(Detached Objects,離線對象):已經被持久化,但不再處於Session的緩存中。Session關閉後,持久化對象就變爲離線對象。離線表示這個對象不能再與數據庫保持同步,它們不再受hibernate管理。
二、Session接口:
是Hibernate嚮應用程序提供的操縱數據的最主要接口,它提供了基本的保存、更新、刪除和查詢方法。
Session具有一個緩存,位於緩存中的對象處於持久化狀態,這和數據庫的相關記錄對應,Session能夠
在某些時間點,按照緩存中持久化對象的屬性變化來同步更新數據庫,這一過程被稱爲“清理緩存”。
1、Session緩存的作用:
1)減少訪問數據庫的操作。
2)保證緩存中的對象與數據庫中的相關記錄保持同步。當緩存中持久化對象的狀態發生了改變,Session
並不會立即執行相關的SQL語句,這使得Session可以把幾條相關的SQL語句合併爲一條SQL語句,以便
減少訪問數據庫的次數,從而提高應用程序的性能。
3)當緩存中的持久化對象之間存在循環關聯關係時,Session會保證不出現訪問對象圖的死循環,以及由
死循環引起的JVM堆棧溢出異常。
2、在默認情況下,Session會在下面的時間點清理緩存:
1)當應用程序調用Transaction的commit()方法時,commit()方法先清理緩存,然後再向數據庫提交事務;
2)當應用程序調用Session的find()或者iterate()方法時,如果緩存中持久化對象的屬性發生了變化,就
會先清理緩存,以保證查詢結果能反映持久化對象的最新狀態;
3)當應用程序顯式調用Session的flush()方法時;
注:Session的commit()和flush()方法的區別。flush()方法進行清理緩存的操作,執行一系列SQL語句,但
不會提交事務;commit()方法會先調用flush()方法,然後提交事務。提交事務意味着對數據庫所做的更新
被永久保存下來。
3、查詢數據:
使用get()和load()方法,兩者的區別:
1)get()方法不支持延遲加載,load()方法支持延遲加載;
2)如果沒有查詢到匹配數據,get()方法會返回null值,而load()方法會拋出ObjectNotFoundException異常;
4、插入數據:save(Object)方法
使一個臨時對象轉變爲持久化對象,save()方法完成以下操作:
1)把臨時對象加入到緩存中,使它變爲持久化對象;
2)選用映射文件指定的標識符生成器爲持久化對象分配惟一的OID;
3)計劃執行一個insert語句,把臨時對象當前的屬性值組裝到insert語句中;
4)注意:save()方法並不立即執行SQL insert語句,只有當Session清理緩存時,纔會執行SQL語句。
如果在save()方法之後,又修改了持久化對象的屬性,這會使得Session在清理緩存時,額外執行
SQL update語句。
5)Hibernate通過持久化對象的OID來維持它與數據庫相關記錄的對應關係。當對象處於持久化狀態時,
不允許程序隨意修改它的OID,否則會導致Session清理緩存時拋出異常。
6)提示:無論Java對象處理臨時狀態、持久化狀態還是遊離狀態,應用程序都不應該修改它的OID。因此
比較安全的做法是:在定義持久化類時,把它的setId()方法設爲private類型,禁止外部程序訪問
該方法。
5、更新數據:update(Object)方法
使一個遊離對象轉變爲持久化對象,update()方法完成以下操作:
1)把遊離對象重新加入到Session緩存中,使它變爲持久化對象;
2)計劃執行一個update語句。Session只有在清理緩存時纔會執行update語句;
3)只要通過update()方法使遊離對象被一個Session關聯,即使沒有修改對象的任何屬性,Session在清理
緩存時也會執行由update()方法計劃的update語句。
4)當update()方法關聯一個遊離對象時,如果在Session緩存中已經存在相同OID的持久化對象,會拋出異常;
5)當update()方法關聯一個遊離對象時,如果在數據庫中不存在相應的記錄,也會拋出異常;
6、刪除數據:delete(Object)方法
從數據庫中刪除與Java對象對應的記錄。如果傳入的參數是持久化對象,Session就計劃執行一個delete語句;
如果傳入的參數是遊離對象,先使遊離對象被Session關聯,使它變爲持久化對象,然後計劃執行一個delete
語句。
三、Query接口:
是HQL(hibernate query language)查詢接口。
1、通過Session的createQuery()方法創建一個Query對象,它包含一個HQL查詢語句。HQL查詢語句可以包含命名參數;
2、動態綁定參數:Query接口提供了給各種命名參數賦值的方法;
3、調用Query接口的list()方法執行查詢語句。該方法返回List類型的查詢結果,在List集合中存放了符合查詢條件的持久化對象;