1. 程式人生 > >分享知識-快樂自己:Hibernate 中 get() 和 load()、sava、update、savaOrUpdate、merge,不同之處及執行原理?

分享知識-快樂自己:Hibernate 中 get() 和 load()、sava、update、savaOrUpdate、merge,不同之處及執行原理?

1):Hibernate 中 get()  和 load() 有什麼不同之處?

1)Hibernate的 get方法,會確認一下該id對應的資料是否存在,首先在session快取中查詢,然後在快取中查詢,還沒有就查詢資料庫,資料庫中沒有就返回null。

2)Hibernate的 load方法載入實體物件的時候,根據對映檔案上類級別的lazy屬性的配置(預設為true):

 ①  若為true,則首先在Session快取中查詢,看看該id對應的物件是否存在,不存在則使用延遲載入,返回實體的代理類物件(該代理類為實體類的子類,由CGLIB動態生成)。

     等到具體使用該物件(除獲取OID以外)的時候,再查詢二級快取和資料庫,若仍沒發現符合條件的記錄,則會丟擲一個ObjectNotFoundException。

     ----

 ②  若 為false,就跟Hibernate的get方法查詢順序一樣,只是最終若沒發現符合條件的記錄,則會丟擲一個ObjectNotFoundException,所說的load方法拋異常是指在使用該物件的資料時,

     資料庫中不存在該資料時拋異常,而不是在建立這個物件時。

2):sava()?

Session的save()方法用來將一個臨時物件轉變為持久化物件,也就是將一個新的實體儲存到資料庫中。通過save()將持久化物件儲存到資料庫需要經過以下步驟:

1,系統根據指定的ID生成策略,為臨時物件生成一個唯一的OID;

2,將臨時物件載入到快取中,使之變成持久化物件;

3,提交事務時,清理快取,利用持久化物件包含的資訊生成insert語句,將持久化物件儲存到資料庫。

提示:儲存的時候跟主鍵生成策略有直接關係,常用屬性如下

<!--手動主鍵生成策略-->

<generator class="assigned"/>

<!--indentity:針對mysql資料庫-->

<!--sequence:針對於oracle資料庫-->

<!--increment:查詢資料庫最大主鍵值+1-->

3):update()?

1):首先你要知道,hibernate的update操作的執行機理:

2):hibernate的update是怎麼樣自動的進行update操作的呢?

3):首先hibernate先會執行一個select操作,到資料庫中查詢

4):當前要update操作的物件的主鍵是否存在,類似於:

5):select id from table where id=XXX

6):如果查詢到了改id,就說明該物件是一個持久化物件,

7):如果該對像的某些屬性變化了,hibernate就會自動的執行update操作,

8):同步資料庫中的該物件。

9):如果資料庫找不到要更新的物件,則會報異常找不到需要更新的物件

提示點:update 預設會更新所有欄位資訊。要想實現動態更新欄位 需要修改對映檔案新增以下配置:dynamic-update="true"

4):savaOrUpdate()?

簡單來說就是 儲存或者更新,那麼是如何實現的那?

儲存:的依據就是,根據當前 new的這個物件判斷他的 OID 是否有效(也可以理解為主鍵在資料庫中是否存在)如果無效則執行儲存操作。

更新:同理儲存的理念,如果OID 有效則執行更新操作。

提示:這裡的更新不會優先執行查詢的SQL語句,而是直接更新所有欄位。

5):merge()?

1):如果merge的物件在資料庫中不存在,merge將會進行save操作,作用等同於updateOrSave();而update因為找不到物件而報錯。)

2):如果merge的物件能在資料庫中操作,merge操作和update操作效果一樣。

3):新new一個物件,如果該物件設定了ID,則這個物件就當作遊離態處理。

4):merge可以持久化遊離態的物件A,持久化後的物件A仍然處於遊離態,持久化的物件A不和session關聯。

5):merge返回持久化物件的副本,該副本處於持久化態。