熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Hibernate復合主鍵映射

2013-11-23 20:41:28  來源: Java開源技術 
    在日常開發中會遇到這樣一種情況數據庫中的某張表需要多個字段列才能唯一確定一行記錄這時表需要使用復合主鍵面對這樣的情況Hibernate為我們提供了兩種方式來解決復合主鍵問題
   
    方式一將復合主鍵對應的屬性與實體其他普通屬性放在一起
   
    例如實體類People中idname屬性對應復合主鍵
   
    /*實體類使用復合主鍵必須實現Serializable接口*/
   
    public class People implements Serializable
   
    {
   
    private static final long serialVersionUID = L;
   
    private String id;
   
    private String name;
   
    private int age;
   
    public People()
   
    {
   
    }
   
    public String getId()
   
    {
   
    return id;
   
    }
   
    public void setId(String id)
   
    {
   
    thisid = id;
   
    }
   
    public String getName()
   
    {
   
    return name;
   
    }
   
    public void setName(String name)
   
    {
   
    thisname = name;
   
    }
   
    public int getAge()
   
    {
   
    return age;
   
    }
   
    public void setAge(int age)
   
    {
   
    thisage = age;
   
    }
   
    @Override
   
    public int hashCode()
   
    {
   
    final int prime = ;
   
    int result = ;
   
    result = prime * result + ((id == null)
   
    ? : idhashCode())
   
    result = prime * result + ((name == null) ? : namehashCode())
   
    return result;
   
    }
   
    @Override
   
    public boolean equals(Object obj)
   
    {
   
    if (this == obj)
   
    return true;
   
    if (obj == null)
   
    return false;
   
    if (getClass() != objgetClass())
   
    return false;
   
    People other = (People) obj;
   
    if (id == null)
   
    {
   
    if (otherid != null)
   
    return false;
   
    }
   
    else if (!idequals(otherid))
   
    return false;
   
    if (name == null)
   
    {
   
    if (othername != null)
   
    return false;
   
    }
   
    else if (!nameequals(othername))
   
    return false;
   
    return true;
   
    }  } Peoplehbmxml:
   
    <?xml version= encoding=utf?>
   
    <!DOCTYPE hibernatemapping PUBLIC //Hibernate/Hibernate Mapping DTD //EN mappingdtd>
   
    <hibernatemapping>
   
    <class name=comsuxiaoleihibernatepojosPeople table=people>
   
    <! 復合主鍵使用compositeid標簽 >
   
    <compositeid>
   
    <! keyproperty標簽表示哪一些屬性對應復合主鍵 >
   
    <keyproperty name=id column=id type=string></keyproperty>
   
    <keyproperty name=name column=name type=string></keyproperty>
   
    </compositeid>
   
    <property name=age column=age type=integer></property>
   
    </class>
   
    </hibernatemapping>
   
    Hibernate中使用復合主鍵時需要注意一些規則
   
    使用復合主鍵的實體類必須實現Serializable接口必須實現Serializable接口的原因很簡單我們查找數據的時候是根據主鍵查找的打開Hibernate的幫助文檔我們可以找到get與load方法的聲明形式如下
   
    Object load(Class theClassSerializable id)
   
    Object get(Class theClassSerializable id)
   
    當我們查找復合主鍵類的對象時需要傳遞主鍵值給get()或load()方法的id參數而id參數只能接收一個實現了Serializable接口的對象而復合主鍵類的主鍵不是一個屬性可以表示的所以只能先new出復合主鍵類的實例(例如new People())然後使用主鍵屬性的set方法將主鍵值賦值給主鍵屬性然後將整個對象傳遞給get()或load()方法的id參數實現主鍵值的傳遞所以復合主鍵的實體類必須實現Serializable接口
   
    使用復合主鍵的實體類必須重寫equals和hashCode方法必須重寫equals和hashCode方法也很好理解這兩個方法使用於判斷兩個對象 (兩條記錄)是否相等的為什麼要判斷兩個對象是否相等呢?因為數據庫中的任意兩條記錄中的主鍵值是不能相同的所以我們在程序中只要確保了兩個對象的主鍵值不同就可以防止主鍵約束違例的錯誤出現也許這裡你會奇怪為什麼不使用復合主鍵的實體類不重寫這兩個方法也沒有主鍵違例的情況出現這是因為使用單一主鍵方式主鍵值是Hibernate來維護的它會確保主鍵不會重復而復合主鍵方式主鍵值是編程人員自己維護的所以必須重寫equals和hashCode方法用於判斷兩個對象的主鍵是否相同
   


    重寫的equals和hashCode方法只與主鍵屬性有關普通屬性不要影響這兩個方法進行判斷這個原因很簡單主鍵才能決定一條記錄其他屬性不能決定一條記錄
   
    保存測試
   
    public class Client  {
   
    public static void main(String[] args)
   
    {
   
    Session session = HibernateUtilgetSessionFactory()openSession()
   
    Transaction tx = null;
   
    try
   
    {
   
    tx = sessionbeginTransaction()
   
    People people = new People()
   
    /*主鍵值由我們自己維護*/
   
    peoplesetId(
   
    peoplesetName(zhangsan
   
    peoplesetAge(
   
    sessionsave(people)
   
    mit()
   
    }
   
    catch (Exception e)
   
    {
   
    if(tx != null)
   
    {
   
    txrollback()
   
    }
   
    eprintStackTrace()
   
    }
   
    finally
   
    {
   
    sessionclose()
   
    }
   
    }
   
    }
   
    看看數據庫
   
    數據被正確的插入到數據庫中了
   
    讀取數據測試
   
    public class Client
   
    {
   
    public static void main(String[] args)
   
    {
   
    Session session = HibernateUtilgetSessionFactory()openSession()
   
    Transaction tx = null;
   
    try
   
    {
   
    tx = sessionbeginTransaction()
   
    /*查詢復合主鍵對象需要先構建主鍵*/
   
    People peoplePrimaryKey = new People()
   
    peoplePrimaryKeysetId(
   
    peoplePrimaryKeysetName(zhangsan
   
    /*然後將構建的主鍵值傳入get方法中獲取對應的People對象*/
   
    People people = (People)sessionget(Peopleclass peoplePrimaryKey)
   
    Systemoutprintln(people age is:+peoplegetAge())
   
    mit()
   
    }
   
    catch (Exception e)
   
    {
   
    if(tx != null)
   
    {
   
    txrollback()
   
    }
   
    eprintStackTrace()
   
    }
   
    finally
   
    {
   
    sessionclose()
   
    }
   
    }
   
    }
   
    控制台輸出
   
    people age is:可以看到數據成功的取出了
   
    方式二將主鍵屬性提取到一個主鍵類中實體類只需包含主鍵類的一個引用
   
    主鍵類
   
    /*必須實現Serializable接口*/
   
    public class PeoplePrimaryKey implements Serializable
   
    {
   
    private static final long serialVersionUID = L;
   
    /*復合主鍵值*/
   
    private String id;
   
    private String name;
   
    public PeoplePrimaryKey()
   
    {
   
    }
   
    /*復合主鍵值的get和set方法*/
   
    public String getId()
   
    {
   
    return id;
   
    }
   
    public void setId(String id)
   
    {
   
    thisid = id;
   
    }
   
    public String getName()
   
    {
   
    return name;
   
    }
   
    public void setName(String name)
   
    {
   
    thisname = name;
   
    }
   
    @Override
   
    public int hashCode()
   
    {
   
    final int prime = ;
   
    int result = ;
   
    result = prime * result + ((id == null) ? : idhashCode())
   
    result = prime * result + ((name == null) ? : namehashCode())
   
    return result;
   
    }
   
    @Override
   
    public boolean equals(Object obj)
   
    {
   
    if (this == obj)
   
    return true;
   
    if (obj == null)
   
    return false;
   
    if (getClass() != objgetClass())
   
    return false;
   
    PeoplePrimaryKey other = (PeoplePrimaryKey) obj;
   
    if (id == null)
   
    {
   
    if (otherid != null)
   
    return false;
   
    }
   
    else if (!idequals(otherid))
   
    return false;
   
    if (name == null)
   
    {
   
    if (othername != null)
   
    return false;
   
    }
   
    else if (!nameequals(othername))
   
    return false;
   
    return true;
   
    }
   
    }


   
    實體類
   
    public class People  {
   
    /*持有主鍵類的一個引用使用該引用作為這個類的OID*/
   
    private PeoplePrimaryKey peoplePrimaryKey;
   
    private int age;
   
    public People()
   
    {
   
    }
   
    public PeoplePrimaryKey getPeoplePrimaryKey()
   
    {
   
    return peoplePrimaryKey;
   
    }
   
    public void setPeoplePrimaryKey(PeoplePrimaryKey peoplePrimaryKey)
   
    {
   
    thispeoplePrimaryKey = peoplePrimaryKey;
   
    }
   
    public int getAge()
   
    {
   
    return age;
   
    }
   
    public void setAge(int age)
   
    {
   
    thisage = age;
   
    }
   
    }
   
    Peoplehbmxml文件稍有一點變動
   
    <?xml version= encoding=utf?>
   
    <!DOCTYPE hibernatemapping PUBLIC //Hibernate/Hibernate Mapping DTD //EN mappingdtd>
   
    <hibernatemapping>
   
    <class name=comsuxiaoleihibernatepojosPeople table=people>
   
    <! 復合主鍵使用compositeid標簽 >
   
    <!          name 指定了復合主鍵對應哪一個屬性
   
    class 指定了復合主鍵屬性的類型          >
   
    <compositeid name=peoplePrimaryKey class=comsuxiaoleihibernatepojosPeoplePrimaryKey>
   
    <! keyproperty指定了復合主鍵由哪些屬性組成 >
   
    <keyproperty name=id column=id type=string></keyproperty>
   
    <keyproperty name=name column=name type=string></keyproperty>
   
    </compositeid>
   
    <property name=age column=age type=integer></property>
   
    </class> </hibernatemapping>
   
    場景測試與方式一大同小異這裡不再舉例了主鍵類為什麼實現Serializable接口和為什麼重寫equals和hashCode方法上面已經解釋的很清楚了


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28901.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.