自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Hibernate的unsaved-value

開發(fā) 后端
本文介紹Hibernate的unsaved-value。unsaved-value="none"和 unsaved-value="any"主要用在主鍵屬性不是通過Hibernate生成,而是程序自己setId()的時候。

當(dāng)你顯式的使用session.save()或者session.update()操作一個對象的時候,實際上是用不到unsaved-value的。某些情況下(父子表關(guān)聯(lián)保存),當(dāng)你在程序中并沒有顯式的使用save或者update一個持久對象,那么Hibernate需要判斷被操作的對象究竟是一個已經(jīng)持久化過的持久對象,是一個尚未被持久化過的內(nèi)存臨時對象。例如:

  1. Session session = ...;   
  2. Transaction tx = ...;   
  3.  
  4. Parent parent = (Parent) session.load(Parent.class, id);   
  5.  
  6. Child child = new Child();   
  7. child.setParent(parent);   
  8. child.setName("sun");   
  9.  
  10. parent.addChild(child);   
  11. s.update(parent);   
  12.  
  13. s.flush();   
  14. tx.commit();   
  15. s.close();   

在上例中,程序并沒有顯式的session.save(child); 那么Hibernate需要知道child究竟是一個臨時對象,還是已經(jīng)在數(shù)據(jù)庫中有的持久對象。如果child是一個新創(chuàng)建的臨時對象(本例中就是這種情況),那么Hibernate應(yīng)該自動產(chǎn)生session.save(child)這樣的操作,如果child是已經(jīng)在數(shù)據(jù)庫中有的持久對象,那么Hibernate應(yīng)該自動產(chǎn)生session.update(child)這樣的操作。

因此我們需要暗示一下Hibernate,究竟child對象應(yīng)該對它自動save還是update。在上例中,顯然我們應(yīng)該暗示Hibernate對child自動save,而不是自動update。那么Hibernate如何判斷究竟對child是save還是update呢?它會取一下child的主鍵屬性 child.getId() ,這里假設(shè)id是 java.lang.Integer類型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate認(rèn)為child是新的內(nèi)存臨時對象,發(fā)送save,如果不相等,那么Hibernate認(rèn)為child是已經(jīng)持久過的對象,發(fā)送update。

unsaved-value="null" (默認(rèn)情況,適用于大多數(shù)對象類型主鍵 Integer/Long/String/...)

當(dāng)Hibernate取一下child的Id,取出來的是null(在上例中肯定取出來的是null),和unsaved-value設(shè)定值相等,發(fā)送save(child)

當(dāng)Hibernate取一下child的id,取出來的不是null,那么和unsaved-value設(shè)定值不相等,發(fā)送update(child)

例如下面的情況:

  1. Session session = ...;   
  2. Transaction tx = ...;   
  3.  
  4. Parent parent = (Parent) session.load(Parent.class, id);   
  5. Child child = (Child) session.load(Child.class, childId);   
  6.  
  7. child.setParent(parent);   
  8. child.setName("sun");   
  9.  
  10. parent.addChild(child);   
  11. s.update(parent);   
  12.  
  13. s.flush();   
  14. tx.commit();   
  15. s.close();   

child已經(jīng)在數(shù)據(jù)庫中有了,是一個持久化的對象,不是新創(chuàng)建的,因此我們希望Hibernate發(fā)送update(child),在該例中,Hibernate取一下child.getId(),和unsave-value指定的null比對一下,發(fā)現(xiàn)不相等,那么發(fā)送update(child)。

BTW: parent對象不需要操心,因為程序顯式的對parent有l(wèi)oad操作和update的操作,不需要Hibernate自己來判斷究竟是save還是update了。我們要注意的只是child對象的操作。另外unsaved-value是定義在Child類的主鍵屬性中的。

  1. < class name="Child" table="child">   
  2. < id column="id" name="id" type="integer" unsaved-value="null">   
  3. < generator class="identity"/>   
  4. < /id>   
  5. ...   
  6. < /class>  

如果主鍵屬性不是對象型,而是基本類型,如int/long/double/...,那么你需要指定一個數(shù)值型的unsaved-value,例如:

  1. unsaved-null="0"  

在此提醒大家,很多人以為對主鍵屬性定義為int/long,比定義為Integer/Long運行效率來得高,認(rèn)為基本類型不需要進(jìn)行對象的封裝和解構(gòu)操作,因此喜歡把主鍵定義為int/long的。但實際上,Hibernate內(nèi)部總是把主鍵轉(zhuǎn)換為對象型進(jìn)行操作的,就算你定義為int/long型的,Hibernate內(nèi)部也要進(jìn)行一次對象構(gòu)造操作,返回給你的時候,還要進(jìn)行解構(gòu)操作,效率可能反而低也說不定。因此大家一定要扭轉(zhuǎn)一個觀點,在Hibernate中,主鍵屬性定義為基本類型,并不能夠比定義為對象型效率來的高,而且也多了很多麻煩,因此建議大家使用對象型的Integer/Long定義主鍵。

unsaved-value="none"和 unsaved-value="any"

主要用在主鍵屬性不是通過Hibernate生成,而是程序自己setId()的時候。

在這里多說一句,強烈建議使用Hibernate的id generator,或者你可以自己擴(kuò)展Hibernate的id generator,特別注意不要使用有實際含義的字段當(dāng)做主鍵來用!例如用戶類User,很多人喜歡用用戶登陸名稱做為主鍵,這是一個很不好的習(xí)慣,當(dāng)用戶類和其他實體類有關(guān)聯(lián)關(guān)系的時候,萬一你需要修改用戶登陸名稱,一改就需要改好幾張表中的數(shù)據(jù)。偶合性太高,而如果你使用無業(yè)務(wù)意義的id generator,那么修改用戶名稱,就只修改user表就行了。

由這個問題引申出來,如果你嚴(yán)格按照這個原則來設(shè)計數(shù)據(jù)庫,那么你基本上是用不到手工來setId()的,你用Hibernate的id generator就OK了。因此你也不需要了解當(dāng)unsaved-value="none"和unsaved-value="any" 究竟有什么含義了。如果你非要用assigned不可,那么繼續(xù)解釋一下:

unsaved-value="none" 的時候,由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對child對象發(fā)送update(child)

unsaved-value="any" 的時候,由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對child對象發(fā)送save(child)

大多數(shù)情況下,你可以避免使用assigned,只有當(dāng)你使用復(fù)合主鍵的時候不得不手工setId(),這時候需要你自己考慮究竟怎么設(shè)置unsaved-value了,根據(jù)你自己的需要來定。

BTW: Gavin King強烈不建議使用composite-id,強烈建議使用UserType。

因此,如果你在系統(tǒng)設(shè)計的時候,遵循如下原則:

1、使用Hibernate的id generator來生成無業(yè)務(wù)意義的主鍵,不使用有業(yè)務(wù)含義的字段做主鍵,不使用assigned。

2、使用對象類型(String/Integer/Long/...)來做主鍵,而不使用基礎(chǔ)類型(int/long/...)做主鍵

3、不使用composite-id來處理復(fù)合主鍵的情況,而使用UserType來處理該種情況。

那么你永遠(yuǎn)用的是unsaved-value="null" ,不可能用到any/none/..了。

【編輯推薦】

  1. 使用MyEclipse開發(fā)***個Hibernate程序
  2. Hibernate 中Clob字段的使用
  3. Hibernate中g(shù)et和load方法的區(qū)別
  4. 項目添加Hibernate支持
  5. Hibernate查詢語言HQL 八大要點
責(zé)任編輯:book05 來源: 百度博客
相關(guān)推薦

2009-06-18 11:43:40

Hibernate uHibernate s

2009-06-26 10:06:00

游離狀態(tài)Hibernate

2012-02-03 11:31:33

HibernateJava

2009-06-06 15:37:22

Hibernate性能

2009-06-26 10:01:00

Hibernate的查

2012-02-03 11:17:33

HibernateJava

2009-07-02 09:40:14

Hibernate的繼

2009-09-25 09:04:27

Hibernate類型

2012-02-08 14:24:35

HibernateJava

2009-09-23 16:30:01

Hibernate f

2009-09-24 08:48:54

Hibernate技術(shù)

2009-06-17 16:08:58

Hibernate C

2009-06-26 16:34:50

delete()方法Hibernate S

2009-06-26 16:33:09

saveOrUpdatHibernate

2009-06-12 15:05:03

cascadeHibernate

2009-06-17 10:33:17

Hibernate 存

2012-06-02 00:55:44

HibernateflushJava

2009-09-23 17:36:26

Hibernate優(yōu)點

2009-09-23 09:16:25

Hibernate復(fù)合

2009-09-22 10:50:04

Hibernate c
點贊
收藏

51CTO技術(shù)棧公眾號