merge() 方法的細微差別
如果你想使用 Hibernate 來改變一個已經存儲在數據庫中的對象,那麼也有幾種方法可以做到這一點。
第一個是merge()方法,它根據傳遞的對象更新數據庫中的信息。這將調用 SQL UPDATE 查詢。例子:
User user = new User();
user.setName("Kolyan");
session.save(user);
session.evict(user); // detach the object from the session
user.setName("Masha");
User user2 = (User) session.merge(user);
這裡有幾個重要的細微差別。
首先,merge()方法返回結果,即更新後的對象。該對象具有 Persist 狀態並附加到會話對象。傳遞給merge()方法的對像不會改變。
user 和 user2 之間似乎沒有區別,但事實並非如此。您可以將一個 POJO 對像傳遞給merge()方法,結果,該方法可以返回一個代理(取決於 Hibernate 設置)。所以請記住merge()方法不會更改傳遞的對象。
其次,如果傳遞給merge()的對象具有 Transient 狀態(並且它沒有 ID),那麼將在數據庫中為其創建一個單獨的行。換句話說,將執行persist()命令。
第三,如果一個已經附加到會話的對象(具有 Persist 狀態)被傳遞給merge()方法,那麼什麼也不會發生——該方法將簡單地返回同一個對象。為什麼?這一切都是因為當事務被提交時,數據無論如何都會被寫入數據庫:
User user = new User();
user.setName("Kolyan");
session.save(user);
user.setName("Masha"); //change the object attached to the session
session.close(); //all changed objects will be written to the database
每次更改後都不需要保存對象。如果這個對象處於 Persist 狀態,那麼 Hibernate 會自己做所有事情。如果更改“附加到基礎”的對象,則其所有更改都將寫入基礎。
update() 方法的細微差別
Hibernate 也有一個update()方法,它和save()方法一樣,是從以前的版本繼承而來的。使用此方法,您只能更新已保存對象的數據。這將調用 SQL UPDATE 查詢。例子:
User user = new User();
user.setName("Kolyan");
session.save(user);
session.evict(user); // detach the object from the session
user.setName("Masha");
session.update(user);
此方法不返回任何內容,也不更改現有對象。
如果您在一個新對像上調用此方法,則會拋出一個異常:
User user = new User();
user.setName("Kolyan");
session.update(user); //an exception will be thrown here
saveOrUpdate() 方法
在JPA出現之前,persist()方法的功能是由saveOrUpdate()方法完成的。他的任務是更新數據庫中現有對象的信息,如果沒有,則創建它。它幾乎總是用來代替save()和update()方法。
與update()方法不同,它可以更改傳遞給它的對象。例如,將其設置為保存到數據庫時分配的 ID。例子:
User user = new User();
user.setName("Kolyan");
session.saveOrUpdate(user); //object will be written to the database
怎麼運行的:
- 如果傳遞的對像有 ID,則調用 UPDATE SQL 方法
- 如果未設置傳遞對象的 ID,則調用 INSERT SQL 方法
GO TO FULL VERSION