<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

      Sparta Yew

         簡(jiǎn)約、職業(yè)、恒久
    隨筆 - 15, 文章 - 1, 評(píng)論 - 276, 引用 - 0
    數(shù)據(jù)加載中……

    hibernate中提倡持久類(lèi)實(shí)現(xiàn)equals()和hashCode()的原因分析


    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)如下代碼:

        private Set<?> sysUsersRoles = new HashSet(0);
        
    private Set<?> sysRolesAuthorities = new HashSet(0);

        
    public Set getSysUsersRoles() {
            
    return this.sysUsersRoles;
        }


        
    public void setSysUsersRoles(Set sysUsersRoles) {
            
    this.sysUsersRoles = sysUsersRoles;
        }


        
    public Set getSysRolesAuthorities() {
            
    return this.sysRolesAuthorities;
        }


        
    public void setSysRolesAuthorities(Set sysRolesAuthorities) {
            
    this.sysRolesAuthorities = sysRolesAuthorities;
        }

        
        按照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ě)在下面吧:

    public boolean equals( Object other ){
            
            
    ifthis == other ) return true;
            
            
    if!( other instanceof Person ) ) return false;
            
            
    final Person person = (Person)other;
            
            
    if!person.getName().equals( getName() ) ) return false;
            
            
    if!person.getAge().equals( getAge())) return false;

            
    if!person.getFartherName().equals( getFartherName())) return false;
            
            
    return true;
            
        }

        
        
    public int hashCode(){
            
    int result;
            
            result 
    = getName().hashCode();
            
            result 
    = 29 * result + getAge();

            result 
    = 29 * result + getFartherName();
            
            
    return result;
    }


    還有,朋友們也可以鍵入以下代碼嘗試一下兩者的區(qū)別:

    public static void main(String[] args){
            
            SysRoles role1 
    = new SysRoles("1","lxb","ljh");
            SysRoles role2 
    = new SysRoles("1","lxb","ljh");
            
            
    /*
             * 經(jīng)過(guò)試驗(yàn),當(dāng)不重寫(xiě)equals和hashCode時(shí)顯示為false;
             * 重寫(xiě)時(shí),顯示為true。
             * 這就是為什么重寫(xiě)equals和hashCode的原因,當(dāng)你希望從hiberate中提取的對(duì)象實(shí)例中,
             * 若是所有字段的內(nèi)容都相同,就認(rèn)為這兩個(gè)對(duì)象實(shí)例是相同的,此時(shí)就需要重寫(xiě)equals和hashCode。
             * 重寫(xiě)equals和hashCode意味著,混雜在不同上下文及Session中的兩個(gè)實(shí)例對(duì)象有了確定的語(yǔ)義。
             
    */

            System.out.println(role1.equals(role2));
            
            
    /*
             * 經(jīng)過(guò)試驗(yàn),當(dāng)不重寫(xiě)equals和hashCode時(shí)顯示為false;
             * 重寫(xiě)時(shí),顯示為true。
             * 
             
    */

            System.out.println(role1.hashCode() 
    == role2.hashCode());
            
    }

        
        哈哈,朋友們自己總結(jié)一下吧!



                -東營(yíng) sparta-紫杉 原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處 :)
                http://www.tkk7.com/SpartaYew/
                SpartaYew@163.com
     
                
    QQ:22086526

    posted on 2011-05-19 10:40 sparta-紫杉 閱讀(3178) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): SSH2

    評(píng)論

    # re: hibernate中提倡持久類(lèi)實(shí)現(xiàn)equals()和hashCode()的原因分析  回復(fù)  更多評(píng)論   

    謝謝,大概看明白了一點(diǎn)點(diǎn),我再看看。
    2014-09-15 11:17 | 小星星
    主站蜘蛛池模板: 成人免费ā片在线观看| 亚洲精品乱码久久久久久蜜桃不卡 | 暖暖在线日本免费中文| 久久99精品免费视频| 理论片在线观看免费| 伊人久久五月丁香综合中文亚洲| 亚洲Av永久无码精品三区在线| 亚洲AV无码成H人在线观看| 亚欧人成精品免费观看| 97无码人妻福利免费公开在线视频| 美女黄频a美女大全免费皮| 亚洲色最新高清av网站| 亚洲国产日产无码精品| 亚洲日本一区二区三区| 国产亚洲AV无码AV男人的天堂| 亚洲А∨精品天堂在线| 免费h成人黄漫画嘿咻破解版| 国产精品成人免费视频网站京东| 最近中文字幕国语免费完整 | 亚洲女同成人AⅤ人片在线观看| 免费高清在线爱做视频| 91免费精品国自产拍在线不卡| 96免费精品视频在线观看| 男人的天堂网免费网站| 国产真人无码作爱免费视频| xxxx日本在线播放免费不卡| 色多多www视频在线观看免费| 色吊丝性永久免费看码 | 久久久久亚洲?V成人无码| 亚洲日韩涩涩成人午夜私人影院| 免费a在线观看播放| 亚洲AV中文无码乱人伦| 久久精品夜色噜噜亚洲A∨| 中文亚洲AV片不卡在线观看| 久久亚洲国产成人影院网站 | 99re6在线精品视频免费播放| 最近免费mv在线观看动漫| 久久国产精品国产自线拍免费| 久久精品中文字幕免费| 无码免费一区二区三区免费播放 | 亚洲日本香蕉视频观看视频|