Hibernate的update與saveOrUpdate區(qū)別
以下代碼運(yùn)行在Hibernate 3.1.3下面,下面的代碼展示了不同情況或狀態(tài)的對象在作更新時(shí)可能發(fā)生的結(jié)果:
??????? session = HibernateUtil.currentSession();
??????? Example exp2 = null ;
??????? Example exp3 = null ;
??????? Example exp1 =null ;
??????? exp1 = (Example)session.load(Example.class,"1?");
??????? exp1.setExampleCode("exp99");
??????? HibernateUtil.closeSession();
????
?????? ?exp1.setExampleCode("1111");
??????? exp1.setCreateDate(DateUtil.getCurrentTimestamp());
????
????
?????? exp2 = new Example();
?????? exp2.setExampleID("2");
?????? exp2.setExampleCode("2222");
????? ?exp2.setCreateDate(DateUtil.getCurrentTimestamp());
?????? exp3 = new Example();
?????? exp3.setExampleID("4");
?????? exp3.setExampleCode("4444");
?????? exp3.setCreateDate(DateUtil.getCurrentTimestamp());
????
????
????? ?session = HibernateUtil.currentSession();
??????? tx = session.beginTransaction();
???????
??????? session.update(exp1);
??????
?????? session.update(exp2);
??
?????? session.update(exp3);
??
?????? tx.commit();
???? ?HibernateUtil.closeSession();
??
這里面有三種情況:
exp1的情況是:與數(shù)據(jù)庫同步過或是從數(shù)據(jù)庫讀取過后,session?關(guān)閉,而后又對exp1進(jìn)行了修改,再從新的session?中將修改與數(shù)據(jù)庫同步。
exp2的情況是:本身未與數(shù)據(jù)庫同步過,但是它所代表的數(shù)據(jù)在數(shù)據(jù)庫中存在
exp3的情況是:本身未與數(shù)據(jù)庫同步過,但是它所代表的數(shù)據(jù)在數(shù)據(jù)庫中不存在
現(xiàn)在對紅色標(biāo)出的代碼部分變化時(shí)對執(zhí)行結(jié)果的影響進(jìn)行分析:
如果是update操作,?這三種情況的結(jié)果如下:
case1:日志中產(chǎn)生一條update語句,并且更新了數(shù)據(jù)庫中的數(shù)據(jù)
case2:日志中產(chǎn)生一條update語句,并且更新了數(shù)據(jù)庫中的數(shù)據(jù)
case3:日志中產(chǎn)生一條update語句,但對數(shù)據(jù)庫沒有影響,因?yàn)楦静淮嬖谀莻€(gè)id對應(yīng)的數(shù)據(jù)
?如果是saveOrUpdate操作,情況則繁瑣一些:
(1)如果指定id 的generator-class="assigned",
??? (1.1)如果指定Id?的 unsaved-value="null"
???????????? 則生成三條update語句
???(1.2)如果沒有指定Id?的 unsaved-value
??????????? 則生成三條insert語句。
?? (1.3)如果指定Id?的 unsaved-value="undefined"
????????????? case1:日志中產(chǎn)生一條update語句,并且更新了數(shù)據(jù)庫中的數(shù)據(jù)
????????????? case2:日志中產(chǎn)生一條update語句,并且更新了數(shù)據(jù)庫中的數(shù)據(jù)
????????????? case3:日志中產(chǎn)生一條insert語句,數(shù)據(jù)庫中插入了一條數(shù)據(jù)
?????????? 但由于在這種條件下?,是強(qiáng)制Hibernate查詢數(shù)據(jù)庫以判斷對象到底是暫態(tài)(transient )還是只是脫管(detached)的,個(gè)人認(rèn)為這樣可能會導(dǎo)致性能不高,所以對于事前已經(jīng)知道是transient狀態(tài)的對象,直接對其進(jìn)行save操作就行了。
(2)其他的generator-class還沒有試過
結(jié)論:Update:是對暫態(tài)(transient )或是只是脫管(detached)的更新操作,對于暫態(tài)對象的更新操作通常不產(chǎn)生效果,對于脫 管對象是做了同步的操作,即數(shù)據(jù)庫的數(shù)據(jù)發(fā)生變化并且對象狀態(tài)也成為托管對象
???????????? SaveOrUpdate : 也是對暫態(tài)(transient )或是只是脫管(detached)的進(jìn)行操作,至于是插入還是更新,則要根據(jù)id 中指定的一些具體條件來分析。但是個(gè)人認(rèn)為在明顯只會發(fā)生插入操作的情況還是盡量避免用saveOrUpdate而直接用save即可。