熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Hibernate的各種保存方式的區別

2013-11-23 20:39:03  來源: Java開源技術 

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

  預備知識

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

  下邊是常見的翻譯辦法

  transient瞬態或者自由態

  persistent持久化狀態

  detached脫管狀態或者游離態

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

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

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

  save()和persist()將會引發SQL的INSERTdelete()會引發SQLDELETE

  而update()或merge()會引發SQLUPDATE對持久化(persistent)實例的修改在刷新提交的時候會被檢測到

  它也會引起SQLUPDATEsaveOrUpdate()或者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看一下雖然實現步驟類似但是還是有細微的差別)

  這裡參考中的一個說明

  

  I found that a lot of people have the same doubt To help to solve this issue

  Im quoting Christian Bauer

  In case anybody finds this thread……

  persist() is well defined It makes a transient instance persistent However

  it doesnt guarantee that the identifier value will be assigned to the persistent

  instance immediately the assignment might happen at flush time The spec doesnt 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 longrunning conversations

  with an extended Session/persistence contextA 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 (eg 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 longrunning conversation with an extended Session/persistence context

  

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

  persist把一個瞬態的實例持久化但是並不保證標識符被立刻填入到持久化實例中標識符的填入可能被推遲

  到flush的時間

  persist保證當它在一個transaction外部被調用的時候並不觸發一個Sql Insert這個功能是很有用的

  當我們通過繼承Session/persistence context來封裝一個長會話流程的時候一個persist這樣的函數是需要的

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

  saveOrUpdateCopymerge和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發生再幾種情況下

  調用某些查詢的時候

  transaction commit的時候

  手動調用flush的時候

  七lock和update區別

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

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

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

  update的操作步驟是

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

  lock的操作步驟是

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


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28830.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.