中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Hibernate的各種保存方式的區別詳解

發布時間:2020-10-08 22:20:37 來源:腳本之家 閱讀:134 作者:徐劉根 欄目:編程語言

hibernate的保存 

hibernate對于對象的保存提供了太多的方法,他們之間有很多不同,這里細說一下,以便區別: 

一、預備知識: 

在所有之前,說明一下,對于hibernate,它的對象有三種狀態,transientpersistentdetached 

下邊是常見的翻譯辦法: 

  • transient:瞬態或者自由態 
  • persistent:持久化狀態 
  • detached:脫管狀態或者游離態 

脫管狀態的實例可以通過調用save()、persist()或者saveOrUpdate()方法進行持久化。 

持久化實例可以通過調用 delete()變成脫管狀態。通過get()或load()方法得到的實例都是持久化狀態的。 

脫管狀態的實例可以通過調用 update()、saveOrUpdate()、lock()或者replicate()進行持久化。 

游離或者自由狀態下的實例可以通過調用merge()方法成為一個新的持久化實例。 

save()和persist()將會引發SQL的INSERT,delete()會引發SQL的DELETE, 

而update()或merge()會引發SQL的UPDATE。

對持久化(persistent)實例的修改在刷新提交的時候會被檢測到,它也會引起SQLUPDATE。saveOrUpdate()或者replicate()會引發SQLINSERT或者UPDATE 

二、save 和update區別 

把這一對放在第一位的原因是因為這一對是最常用的。 

save的作用是把一個新的對象保存 

update是把一個脫管狀態的對象保存 

三,update 和saveOrUpdate區別 

這個是比較好理解的,顧名思義,saveOrUpdate基本上就是合成了save和update 

引用hibernate reference中的一段話來解釋他們的使用場合和區別 

通常下面的場景會使用update()或saveOrUpdate(): 

程序在第一個session中加載對象 

該對象被傳遞到表現層 

對象發生了一些改動 

該對象被返回到業務邏輯層 

程序調用第二個session的update()方法持久這些改動 

saveOrUpdate()做下面的事: 

  • 如果對象已經在本session中持久化了,不做任何事 
  • 如果另一個與本session關聯的對象擁有相同的持久化標識(identifier),拋出一個異常 
  • 如果對象沒有持久化標識(identifier)屬性,對其調用save() 
  • 如果對象的持久標識(identifier)表明其是一個新實例化的對象,對其調用save() 
  • 如果對象是附帶版本信息的(通過<version>或<timestamp>) 并且版本屬性的值表明其是一個新實例化的對象,save()它。 
  • 否則update() 這個對象 

四,persist和save區別 

這個是最迷離的一對,表面上看起來使用哪個都行,在hibernate reference文檔中也沒有明確的區分他們. 

這里給出一個明確的區分。(可以跟進src看一下,雖然實現步驟類似,但是還是有細微的差別) 

這里參考http://opensource.atlassian.com/projects/hibernate/browse/HHH-1682中的一個說明: 

---------------------------------------------------------------------------------
I found that a lot of people have the same doubt. To help to solve this issue
I'm quoting Christian Bauer:
"In case anybody finds this thread...
persist() is well defined. It makes a transient instance persistent. However,
it doesn't guarantee that the identifier value will be assigned to the persistent
instance immediately, the assignment might happen at flush time. The spec doesn't say
that, which is the problem I have with persist().
persist() also guarantees that it will not execute an INSERT statement if it is
called outside of transaction boundaries. This is useful in long-running conversations
with an extended Session/persistence context.A method like persist() is required.
save() does not guarantee the same, it returns an identifier, and if an INSERT
has to be executed to get the identifier (e.g. "identity" generator, not "sequence"),
this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context."
---------------------------------------------------------------------------------

簡單翻譯一下上邊的句子的主要內容: 

1,persist把一個瞬態的實例持久化,但是并"不保證"標識符被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時間。 

2,persist"保證",當它在一個transaction外部被調用的時候并不觸發一個Sql Insert,這個功能是很有用的,當我們通過繼承Session/persistence context來封裝一個長會話流程的時候,一個persist這樣的函數是需要的。 

3,save"不保證"第2條,它要返回標識符,所以它會立即執行Sql insert,不管是不是在transaction內部還是外部 

五,saveOrUpdateCopy,merge和update區別 

首先說明merge是用來代替saveOrUpdateCopy的

然后比較update和merge 

update的作用上邊說了,這里說一下merge的 

如果session中存在相同持久化標識(identifier)的實例,用用戶給出的對象的狀態覆蓋舊有的持久實例 

如果session沒有相應的持久實例,則嘗試從數據庫中加載,或創建新的持久化實例,最后返回該持久實例 

用戶給出的這個對象沒有被關聯到session上,它依舊是脫管的 

重點是最后一句: 

當我們使用update的時候,執行完成后,我們提供的對象A的狀態變成持久化狀態但當我們使用merge的時候,執行完成,我們提供的對象A還是脫管狀態,hibernate或者new了一個B,或者檢索到一個持久對象B,并把我們提供的對象A的所有的值拷貝到這個B,執行完成后B是持久狀態,而我們提供的A還是托管狀態 

六,flush和update區別 

這兩個的區別好理解 

update操作的是在脫管狀態的對象 

而flush是操作的在持久狀態的對象。 

默認情況下,一個持久狀態的對象是不需要update的,只要你更改了對象的值,等待hibernate flush就自動保存到數據庫了。hibernate flush發生再幾種情況下: 

  • 1,調用某些查詢的時候 
  • 2,transaction commit的時候 
  • 3,手動調用flush的時候 

七,lock和update區別 

update是把一個已經更改過的脫管狀態的對象變成持久狀態 

lock是把一個沒有更改過的脫管狀態的對象變成持久狀態 

對應更改一個記錄的內容,兩個的操作不同: 

update的操作步驟是: 

(1)更改脫管的對象->調用update 

lock的操作步驟是: 

(2)調用lock把對象從脫管狀態變成持久狀態-->更改持久狀態的對象的內容-->等待flush或者手動flush

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。如果你想了解更多相關內容請查看下面相關鏈接

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

油尖旺区| 柘荣县| 永济市| 墨竹工卡县| 江永县| 平塘县| 华容县| 永城市| 德兴市| 望奎县| 本溪市| 灵石县| 元氏县| 桂东县| 巍山| 建始县| 舒兰市| 毕节市| 德江县| 北安市| 浦北县| 岢岚县| 新沂市| 正阳县| 乐安县| 祁阳县| 郸城县| 罗田县| 九江市| 疏勒县| 南昌县| 嫩江县| 淄博市| 象山县| 乌拉特后旗| 墨竹工卡县| 阿克苏市| 南丹县| 金寨县| 昭通市| 兴国县|