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

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

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

      Sparta Yew

         簡約、職業、恒久
    隨筆 - 15, 文章 - 1, 評論 - 276, 引用 - 0
    數據加載中……

    hibernate中提倡持久類實現equals()和hashCode()的原因分析


    sparta-紫杉  11/4/21  17:18


        讀《Hibernate3.0.2完整中文教程》中的“5.5 實現equals()和hashCode()”一文,在本文中強調,當對于多表關聯的數據進行操作時,尤其想把持久類的實例放入Set時(在Hibernate中這種操作尤其常見),或者想重用脫管實例時,均需要對equals()和hashCode()方法進行重寫。

        原因是由于在Hibernate中,需要保證持久化標識(數據庫的行)和僅在特定會話范圍內的Java標識是等值的。我們必然希望Set有明確的語義,以避免混合了來自不同會話中獲取的實例,從而確保數據的持久化不會發生錯誤。

        若使用過Set,你會知道Set中是不允許存儲重復值的,這也是為什么Hibernate推薦在多表關聯的映射中采用Set作為存儲實體對象的主要原因。在多表關聯映射中的持久類中,常見如下代碼:

        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的提倡,應該在該持久化類里,重寫equals()和hashCode()方法。那么為什么要對這兩個方法進行重寫呢? Set里面不是不允許有重復的值嗎?
    重寫這兩個方法究竟能起到什么作用?equals()和hashCode()的意義究竟是什么?

    這是我看到Hibernate提倡的重寫這兩個方法之后我的疑問!

    不妨先來探討一下equals()和hashCode()的作用吧。

    實際上,equals()和hashCode()這兩個方法存在的意義是為了區別對象。這兩個方法均來自于Object類。

    在對象運行期間,為了在運行期區別各對象,就是通過這兩個方法,它們之間的區別如下:

    1.Object類的public boolean equals(Object obj)方法是通過 return this == obj;這種方式比較兩個對象是否相同。這里比較的是引用。
    2.Object類的public int hashCode()方法,是通過該實例地址轉換為int值。所以不同的Object實例在同一運行期hashCode一定不相同。

    現在解決了equals()和hashCode()是什么以及什么作用的問題。

    那么再來談談Hibernate的運行機理吧:
        在Hibernate的運行期內,通過find或者其他方式提取的對象列表,在不同上下文的操作中,或者在瞬時、持久、脫管三種狀態的變換中,為了避免類名相同,但對象內容不同的實例互相碰撞造成混亂,就需要采用更加準確的區別對象的方法,而此時的equals()和hashCode()已經不能滿足要求,只有對這兩個方法進行重寫,增加對這些持久類的各屬性的內容進行區分,才能真正區分從Hibernate的find方法中提取的對象。

    那么什么樣的實例才算是相同的呢? 當然除了你的持久類名標識之外,還需要明確的標識出持久化實例中某些屬性的值也是相等的,兩個實例才算是真正相同。

    比如以下兩行數據來自于Person表(字段內容包括ID,姓名name,年齡age,父親姓名fartherName),這是實例相同的例證:

    1,王長江,30,王有才;
    1,王長江,30,王有才;

    以下兩行實例是不相同的例證:
    1,王長江,30,王有才;
    1,王長江,30,王有財;

    哈哈,看出區別來了嗎? 只有一字只差,就會在Hibernate管理的實例中被看作兩個實例,這就是你重寫hashCode()的重要作用。

    順便將重寫的hashCode()和equals()也寫在下面吧:

    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;
    }


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

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

            System.out.println(role1.equals(role2));
            
            
    /*
             * 經過試驗,當不重寫equals和hashCode時顯示為false;
             * 重寫時,顯示為true。
             * 
             
    */

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

        
        哈哈,朋友們自己總結一下吧!



                -東營 sparta-紫杉 原創,轉載請注明出處 :)
                http://m.tkk7.com/SpartaYew/
                SpartaYew@163.com
     
                
    QQ:22086526

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

    評論

    # re: hibernate中提倡持久類實現equals()和hashCode()的原因分析  回復  更多評論   

    謝謝,大概看明白了一點點,我再看看。
    2014-09-15 11:17 | 小星星
    主站蜘蛛池模板: 久久久精品免费国产四虎| 中文字幕不卡免费高清视频| 131美女爱做免费毛片| 久久亚洲精品成人综合| 国产午夜不卡AV免费| 免费成人福利视频| 亚洲视频一区二区在线观看| 99久久久国产精品免费牛牛| 亚洲黄网在线观看| 很黄很色很刺激的视频免费| 三上悠亚亚洲一区高清| 亚洲一区二区三区高清视频| 最近最新高清免费中文字幕| 亚洲黄色免费电影| 久久久久免费看黄A片APP| 亚洲成a人无码亚洲成av无码| 免费中文字幕一级毛片| 亚洲国产成人综合| 成年女人18级毛片毛片免费| 小说专区亚洲春色校园| 国产国拍精品亚洲AV片| 午夜免费啪视频在线观看| 亚洲精品高清在线| a级毛片在线视频免费观看| 亚洲人成电影在线天堂| 免费看国产成年无码AV片| 日本免费精品一区二区三区| 人人狠狠综合久久亚洲88| www成人免费观看网站| 免费夜色污私人影院在线观看| 又长又大又粗又硬3p免费视频| 国产99视频精品免费视频7| 2022国内精品免费福利视频 | 国产精品久久久久久亚洲小说| 五月婷婷在线免费观看| 亚洲AV色欲色欲WWW| 国产AV无码专区亚洲AV男同| 野花高清在线观看免费完整版中文| 美女无遮挡免费视频网站| 久久精品国产亚洲AV麻豆~| 成人免费毛片内射美女APP|