sparta-紫杉 11/4/21 17:18
讀《Hibernate3.0.2完整中文教程》中的“5.5 實(shí)現(xiàn)equals()和hashCode()”一文,在本文中強(qiáng)調(diào),當(dāng)對(duì)于多表關(guān)聯(lián)的數(shù)據(jù)進(jìn)行操作時(shí),尤其想把持久類(lèi)的實(shí)例放入Set時(shí)(在Hibernate中這種操作尤其常見(jiàn)),或者想重用脫管實(shí)例時(shí),均需要對(duì)equals()和hashCode()方法進(jìn)行重寫(xiě)。
原因是由于在Hibernate中,需要保證持久化標(biāo)識(shí)(數(shù)據(jù)庫(kù)的行)和僅在特定會(huì)話(huà)范圍內(nèi)的Java標(biāo)識(shí)是等值的。我們必然希望Set有明確的語(yǔ)義,以避免混合了來(lái)自不同會(huì)話(huà)中獲取的實(shí)例,從而確保數(shù)據(jù)的持久化不會(huì)發(fā)生錯(cuò)誤。
若使用過(guò)Set,你會(huì)知道Set中是不允許存儲(chǔ)重復(fù)值的,這也是為什么Hibernate推薦在多表關(guān)聯(lián)的映射中采用Set作為存儲(chǔ)實(shí)體對(duì)象的主要原因。在多表關(guān)聯(lián)映射中的持久類(lèi)中,常見(jiàn)如下代碼:
按照Hibernate的提倡,應(yīng)該在該持久化類(lèi)里,重寫(xiě)equals()和hashCode()方法。那么為什么要對(duì)這兩個(gè)方法進(jìn)行重寫(xiě)呢? Set里面不是不允許有重復(fù)的值嗎?重寫(xiě)這兩個(gè)方法究竟能起到什么作用?equals()和hashCode()的意義究竟是什么?
這是我看到Hibernate提倡的重寫(xiě)這兩個(gè)方法之后我的疑問(wèn)!
不妨先來(lái)探討一下equals()和hashCode()的作用吧。
實(shí)際上,equals()和hashCode()這兩個(gè)方法存在的意義是為了區(qū)別對(duì)象。這兩個(gè)方法均來(lái)自于Object類(lèi)。
在對(duì)象運(yùn)行期間,為了在運(yùn)行期區(qū)別各對(duì)象,就是通過(guò)這兩個(gè)方法,它們之間的區(qū)別如下:
1.Object類(lèi)的public boolean equals(Object obj)方法是通過(guò) return this == obj;這種方式比較兩個(gè)對(duì)象是否相同。這里比較的是引用。2.Object類(lèi)的public int hashCode()方法,是通過(guò)該實(shí)例地址轉(zhuǎn)換為int值。所以不同的Object實(shí)例在同一運(yùn)行期hashCode一定不相同。
現(xiàn)在解決了equals()和hashCode()是什么以及什么作用的問(wèn)題。
那么再來(lái)談?wù)凥ibernate的運(yùn)行機(jī)理吧: 在Hibernate的運(yùn)行期內(nèi),通過(guò)find或者其他方式提取的對(duì)象列表,在不同上下文的操作中,或者在瞬時(shí)、持久、脫管三種狀態(tài)的變換中,為了避免類(lèi)名相同,但對(duì)象內(nèi)容不同的實(shí)例互相碰撞造成混亂,就需要采用更加準(zhǔn)確的區(qū)別對(duì)象的方法,而此時(shí)的equals()和hashCode()已經(jīng)不能滿(mǎn)足要求,只有對(duì)這兩個(gè)方法進(jìn)行重寫(xiě),增加對(duì)這些持久類(lèi)的各屬性的內(nèi)容進(jìn)行區(qū)分,才能真正區(qū)分從Hibernate的find方法中提取的對(duì)象。
那么什么樣的實(shí)例才算是相同的呢? 當(dāng)然除了你的持久類(lèi)名標(biāo)識(shí)之外,還需要明確的標(biāo)識(shí)出持久化實(shí)例中某些屬性的值也是相等的,兩個(gè)實(shí)例才算是真正相同。
比如以下兩行數(shù)據(jù)來(lái)自于Person表(字段內(nèi)容包括ID,姓名name,年齡age,父親姓名fartherName),這是實(shí)例相同的例證:
1,王長(zhǎng)江,30,王有才;1,王長(zhǎng)江,30,王有才;
以下兩行實(shí)例是不相同的例證:1,王長(zhǎng)江,30,王有才;1,王長(zhǎng)江,30,王有財(cái);
哈哈,看出區(qū)別來(lái)了嗎? 只有一字只差,就會(huì)在Hibernate管理的實(shí)例中被看作兩個(gè)實(shí)例,這就是你重寫(xiě)hashCode()的重要作用。
順便將重寫(xiě)的hashCode()和equals()也寫(xiě)在下面吧:
還有,朋友們也可以鍵入以下代碼嘗試一下兩者的區(qū)別:
哈哈,朋友們自己總結(jié)一下吧!
posted on 2011-05-19 10:40 sparta-紫杉 閱讀(3178) 評(píng)論(1) 編輯 收藏 所屬分類(lèi): SSH2
Powered by: BlogJava Copyright © sparta-紫杉