日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

save(),saveOrUpdate(),merge()的区别

發(fā)布時(shí)間:2023/12/10 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 save(),saveOrUpdate(),merge()的区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

save(),saveOrUpdate(),merge()的區(qū)別

?

?Save

?save()方法能夠保存實(shí)體到數(shù)據(jù)庫,正如方法名稱save這個(gè)單詞所表明的意思。我們能夠在事務(wù)之外調(diào)用這個(gè)方法,這也是我不喜歡使用這個(gè)方法保存數(shù)據(jù)的原因。假如兩個(gè)實(shí)體之間有關(guān)系(例如employee表和address表有一對(duì)一關(guān)系),如果在沒有事務(wù)的情況下調(diào)用這個(gè)方法保存employee這個(gè)實(shí)體,除非調(diào)用flush()這個(gè)方法,否則僅僅employee實(shí)體會(huì)被保存。?

?saveOrUpdate

?saveOrUpdate()方法會(huì)執(zhí)行插入或者更新操作。如果該對(duì)象在數(shù)據(jù)庫中已經(jīng)存在則更新,不存在則插入。

saveOrUpdate()方法可以在沒有事務(wù)的情況下執(zhí)行,但是如果沒有手動(dòng)調(diào)用flush()方法會(huì)面臨關(guān)聯(lián)對(duì)象不被保存的問題

save()方法與saveOrUpdate()方法最大的不同點(diǎn)在于,saveOrUpdate()方法會(huì)將實(shí)體對(duì)象添加到持久化上下文中,該實(shí)體的后續(xù)改變會(huì)被跟蹤。

HibernateSaveOrUpdateExample.java

以下是簡單的hibernate程序,演示saveOrUpdate()方法的使用。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 /* ?* @(#)HibernateSaveOrUpdateExample.java??? Created on 2016年4月10日 ?* Copyright (c) 2016. All rights reserved. ?*/ package?nd.esp.com.hibernate.example; import?nd.esp.com.hibernate.model.Address; import?nd.esp.com.hibernate.model.Employee; import?nd.esp.com.hibernate.utils.HibernateUtil; import?org.hibernate.Session; import?org.hibernate.SessionFactory; import?org.hibernate.Transaction; public?class?HibernateSaveOrUpdateExample { ????public?static?void?main(String[] args) { ????????// Prep Work ????????SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); ????????System.out.println("***********************************************"); ????????// saveOrUpdate example - without transaction ????????Session session5 = sessionFactory.openSession(); ????????Employee emp5 = getTestEmployee(); ????????session5.saveOrUpdate(emp5); ????????System.out.println("***********************************************"); ????????// saveOrUpdate example - with transaction ????????Session session3 = sessionFactory.openSession(); ????????Transaction tx3 = session3.beginTransaction(); ????????Employee emp3 = getTestEmployee(); ????????session3.saveOrUpdate(emp3); ????????emp3.setName("Kumar");?// will be saved into DB ????????System.out.println("9. Before committing saveOrUpdate transaction. Id="?+ emp3.getId()); ????????tx3.commit(); ????????System.out.println("10. After committing saveOrUpdate transaction"); ????????System.out.println("***********************************************"); ????????Transaction tx4 = session3.beginTransaction(); ????????emp3.setName("Updated Test Name");?// Name changed ????????emp3.getAddress().setCity("Updated City"); ????????session3.saveOrUpdate(emp3); ????????emp3.setName("Kumar");?// again changed to previous value, so no Employee update ????????System.out.println("11. Before committing saveOrUpdate transaction. Id="?+ emp3.getId()); ????????tx4.commit(); ????????System.out.println("12. After committing saveOrUpdate transaction"); ????????System.out.println("***********************************************"); ????????// Close resources ????????sessionFactory.close(); ????} ????public?static?Employee getTestEmployee() { ????????Employee emp =?new?Employee(); ????????Address add =?new?Address(); ????????emp.setName("Test Emp"); ????????add.setCity("Test City"); ????????emp.setAddress(add); ????????add.setEmployee(emp); ????????return?emp; ????} }

  

執(zhí)行上述示例程序,輸出結(jié)果。

1 2 3 4 5 6 7 8 9 10 11 12 13 *********************************************** Hibernate: insert into EMPLOYEE (emp_name) values (?) *********************************************** Hibernate: insert into EMPLOYEE (emp_name) values (?) 9. Before committing saveOrUpdate transaction. Id=21 Hibernate: insert into ADDRESS (city, emp_id) values (?, ?) Hibernate: update EMPLOYEE set emp_name=? where emp_id=? 10. After committing saveOrUpdate transaction *********************************************** 11. Before committing saveOrUpdate transaction. Id=21 Hibernate: update ADDRESS set city=? where emp_id=? 12. After committing saveOrUpdate transaction ***********************************************

  

注意如果沒有事務(wù),僅僅是employee實(shí)體被保存到數(shù)據(jù)庫,而address的信息丟失了。

在事務(wù)tx4中的幾行代碼employee實(shí)體的name屬性先被修改為“Updated Test Name”,之后又被賦值為原來的值“Kumar”,因此employee這個(gè)實(shí)體在事務(wù)提交之前并沒有改變,所以并沒有update操作。

?

Hibernate的merge()方法

HibernateSQL

????? 下面來講講Hibernate的merge方法。我打算按照hibernate對(duì)象生命周期的三個(gè)狀態(tài)來講。

1:如果POJO對(duì)象處于游離態(tài),我所說的游離態(tài)是指該對(duì)象的id值為空。hibernate判斷一個(gè)對(duì)象在數(shù)據(jù)庫中是否存在不是看對(duì)象的其他信息,而是判斷該id在數(shù)據(jù)庫中是不是存在。如果id為空,那自然是不存在,所以當(dāng)我們調(diào)用merge方法的時(shí)候,就會(huì)直接執(zhí)行插入操作。這一點(diǎn)有點(diǎn)像saveorupdate()方法。看一段代碼:

?

再看hibernate的sql語句:

?

二:脫管態(tài):如果我們把上面代碼里//user.setId(4);的注釋去掉,那么它就變成了脫管的對(duì)象了(其實(shí)從游離到脫管就這么簡單,沒有官方說的那么邪乎...)。這是我們?cè)賮砜纯刂婆_(tái)的sql打印:

?看到?jīng)]有,因?yàn)閕d不為空了,所以hibernate就不會(huì)再insert了。由于該對(duì)象的信息和數(shù)據(jù)庫里的一模一樣,所以hibernate只執(zhí)行了一個(gè)select語句,并沒有update,如果我們把字段的值做稍微的變動(dòng),那么控制臺(tái)打印的sql語句還應(yīng)該有一條update語句。就這一點(diǎn)來說,merge還有和saveorupdate()方法一樣。

?

?

三:持久態(tài):持久態(tài)更好理解。如果我們從數(shù)據(jù)庫里get一條記錄,那么這條記錄就處于持久態(tài),如果再調(diào)用merge,那么hibernate就會(huì)先判斷該記錄是否被修改,沒有則什么也不干,修改了就update。這一點(diǎn)還是和saveorupdate()有點(diǎn)像。

  • Session?session?=?this.getSession(); ??
  • Transaction?tr?=?session.beginTransaction(); ??
  • User?exituser?=?(User)session.get(User.class,?new?Integer(1)); ??
  • exituser.setAge(11); ??
  • session.merge(exituser); ??
  • tr.commit(); ??
  • session.close();??
  • Session?session?=?this.getSession();??
  • Transaction?tr?=?session.beginTransaction();??
  • User?exituser?=?(User)session.get(User.class,?new?Integer(1));??
  • exituser.setAge(11);??
  • session.merge(exituser);??
  • tr.commit();??
  • session.close();??
  • ?再看控制臺(tái)打印結(jié)果:

    ??如果沒有對(duì)記錄進(jìn)行修改則不會(huì)有后面的那條update語句。

    ?

    那么merge和saveorupdate()到底有什么區(qū)別呢?看一段代碼:

    ?運(yùn)行上面的代碼,hibernate給我們報(bào)了一個(gè)錯(cuò)誤:a different object with the same identifier value was already associated with the session。意思是,在session緩存中以兩個(gè)標(biāo)識(shí)相同的對(duì)象,這是不可以的。那么,吧update改成merge會(huì)怎么樣呢?改為merge后,一切OK,運(yùn)行正常。其實(shí)merge在執(zhí)行更新之前會(huì)將兩個(gè)標(biāo)識(shí)符相同的對(duì)象進(jìn)行合并,具體合并的方向是向exituser2合并。

    轉(zhuǎn)載于:https://www.cnblogs.com/Smile-123/p/5826763.html

    總結(jié)

    以上是生活随笔為你收集整理的save(),saveOrUpdate(),merge()的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。