這些操作對(duì)經(jīng)常使用hibernate的同學(xué)已經(jīng)很熟悉了,我也經(jīng)常用但一些細(xì)節(jié)并不了解,
最近遇到問題才開始有看了一下。
在讀完robbin的這兩個(gè)精華貼的時(shí)候,感覺清晰了很多,確實(shí)好文章。
http://www.javaeye.com/topic/2712
http://www.javaeye.com/topic/1604?page=1
還有這個(gè)精華貼
http://www.javaeye.com/topic/7484
也很不錯(cuò)。
里面總結(jié)的很好了,我結(jié)合以上三個(gè)帖子、自己的試驗(yàn)(版本hibernate-3.0.5)和Hibernate文檔也總結(jié)了一點(diǎn),加深理解。希望對(duì)剛開始學(xué)Hibernate的同學(xué)有所幫助。
一、saveorUpdate與unsaved-value
到底是sava還是update
Hibernate需要判斷被操作的對(duì)象究竟是一個(gè)已經(jīng)持久化過的持久對(duì)象還是臨時(shí)對(duì)象。
1).主鍵Hibernate的id generator產(chǎn)生
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="increment" />
</id>
Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);
1、默認(rèn)unsaved-value="null"
主鍵是對(duì)象類型,hebernate判斷project的主鍵是否位null,來判斷project是否已被持久化
是的話,對(duì)project對(duì)象發(fā)送save(project),
若自己設(shè)置了主鍵則直接生成update的sql,發(fā)送update(project),即便數(shù)據(jù)庫里沒有那條記錄。
主鍵是基本類型如int/long/double/
自己設(shè)置unsaved-null="0"。
所以這樣的話save和update操作肯定不會(huì)報(bào)錯(cuò)。
2、unsaved-value="none",
由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對(duì)project對(duì)象發(fā)送update(project)
3、unsaved-value="any"
由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對(duì)project對(duì)象發(fā)送save(project),hibernate生成主鍵。
Hibernate文檔中寫到
saveOrUpdate()完成了如下工作:
如果對(duì)象已經(jīng)在這個(gè)session中持久化過了,什么都不用做
如果對(duì)象沒有標(biāo)識(shí)值,調(diào)用save()來保存它
如果對(duì)象的標(biāo)識(shí)值與unsaved-value中的條件匹配,調(diào)用save()來保存它
如果對(duì)象使用了版本(version或timestamp),那么除非設(shè)置unsaved-value="undefined",版本檢查會(huì)發(fā)生在標(biāo)識(shí)符檢查之前.
如果這個(gè)session中有另外一個(gè)對(duì)象具有同樣的標(biāo)識(shí)符,拋出一個(gè)異常
2).主鍵由自己來賦值
<id name="id" type="java.lang.Long">
<column name="ID" precision="22" scale="0" />
<generator class="assigned" />
</id>
Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);
1、默認(rèn)unsaved-value="null"
這時(shí)有所不同,hibernate會(huì)根據(jù)主鍵產(chǎn)生一個(gè)select,來判斷此對(duì)象是否已被持久化
已被持久化則update,未被持久化則save。
2、unsaved-value="none",update對(duì)象,同上
3、unsaved-value="any" ,save對(duì)象,
如果自己自己設(shè)置的ID在數(shù)據(jù)庫中已存在,則報(bào)錯(cuò)。
二、save與update操作
顯式的使用session.save()或者session.update()操作一個(gè)對(duì)象的時(shí)候,實(shí)際上是用不到unsaved-value的
在同一Session,save沒什么可說得
update對(duì)象時(shí), 最直接的更改一個(gè)對(duì)象的方法就是load()它,保持Session打開,然后直接修改即可:
Session s =…
Project p = (Project) sess.load(Project.class, id) );
p.setName(“test”);
s.flush();
不用調(diào)用s.update(p);hibernate能察覺到它的變化,會(huì)自動(dòng)更新。當(dāng)然顯示調(diào)用的話也不會(huì)錯(cuò)
Hibernate文檔中寫到
update()方法在下列情形下使用:
程序在前面的session中裝載了對(duì)象
對(duì)象被傳遞到UI(界面)層
對(duì)該對(duì)象進(jìn)行了一些修改
對(duì)象被傳遞回業(yè)務(wù)層
應(yīng)用程序在第二個(gè)session中調(diào)用update()保存修改
三、delete操作
刪除時(shí)直接自己構(gòu)造一個(gè)project即可刪除
this.projectDao.delete(preojct);
以前刪除我是這樣寫的
public void deleteProject(String id) {
Project project = (Project) this.projectDao.get(Project.class, id);
if (project != null) {
this.projectDao.delete(project);
}
即這樣也是可以的
Project project = new Project();
project.setId(id);
this.projectDao.delete(project).
如果有級(jí)聯(lián)關(guān)系,需要把級(jí)聯(lián)的子類也構(gòu)造出來add進(jìn)去,同樣可以刪除。
好了,羅嗦的夠多了。