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

Hibernate復(fù)合主鍵映射

開發(fā) 后端
在日常開發(fā)中會(huì)遇到這樣一種情況,數(shù)據(jù)庫中的某張表需要多個(gè)字段列才能唯一確定一行記錄,這時(shí)表需要使用復(fù)合主鍵。面對(duì)這樣的情況Hibernate為我們提供了兩種方式來解決復(fù)合主鍵問題。

目 錄:

1. 實(shí)現(xiàn)方式一:將復(fù)合主鍵對(duì)應(yīng)的屬性與實(shí)體其他普通屬性放在一起

2. 實(shí)現(xiàn)方式二:將主鍵屬性提取到一個(gè)主鍵類中,實(shí)體類只需包含主鍵類的一個(gè)引用

在日常開發(fā)中會(huì)遇到這樣一種情況,數(shù)據(jù)庫中的某張表需要多個(gè)字段列才能唯一確定一行記錄,這時(shí)表需要使用復(fù)合主鍵。面對(duì)這樣的情況Hibernate為我們提供了兩種方式來解決復(fù)合主鍵問題。

方式一:將復(fù)合主鍵對(duì)應(yīng)的屬性與實(shí)體其他普通屬性放在一起

例如實(shí)體類People中"id"和"name"屬性對(duì)應(yīng)復(fù)合主鍵:

  1. /*實(shí)體類,使用復(fù)合主鍵必須實(shí)現(xiàn)Serializable接口*/ 
  2. public class People implements Serializable  
  3. {  
  4.     private static final long serialVersionUID = -4888836126783955019L;  
  5.       
  6.     private String id;  
  7.     private String name;  
  8.     private int age;  
  9.       
  10.     public People()  
  11.     {  
  12.           
  13.     }  
  14.  
  15.     public String getId()  
  16.     {  
  17.         return id;  
  18.     }  
  19.  
  20.     public void setId(String id)  
  21.     {  
  22.         this.id = id;  
  23.     }  
  24.  
  25.     public String getName()  
  26.     {  
  27.         return name;  
  28.     }  
  29.  
  30.     public void setName(String name)  
  31.     {  
  32.         this.name = name;  
  33.     }  
  34.  
  35.     public int getAge()  
  36.     {  
  37.         return age;  
  38.     }  
  39.  
  40.     public void setAge(int age)  
  41.     {  
  42.         this.age = age;  
  43.     }  
  44.  
  45.     @Override 
  46.     public int hashCode()  
  47.     {  
  48.         final int prime = 31;  
  49.         int result = 1;  
  50.         result = prime * result + ((id == null) ? 0 : id.hashCode());  
  51.         result = prime * result + ((name == null) ? 0 : name.hashCode());  
  52.         return result;  
  53.     }  
  54.  
  55.     @Override 
  56.     public boolean equals(Object obj)  
  57.     {  
  58.         if (this == obj)  
  59.             return true;  
  60.         if (obj == null)  
  61.             return false;  
  62.         if (getClass() != obj.getClass())  
  63.             return false;  
  64.         People other = (People) obj;  
  65.         if (id == null)  
  66.         {  
  67.             if (other.id != null)  
  68.                 return false;  
  69.         }  
  70.         else if (!id.equals(other.id))  
  71.             return false;  
  72.         if (name == null)  
  73.         {  
  74.             if (other.name != null)  
  75.                 return false;  
  76.         }  
  77.         else if (!name.equals(other.name))  
  78.             return false;  
  79.         return true;  
  80.     }  

People.hbm.xml:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3.  
  4. <hibernate-mapping> 
  5.     <class name="com.suxiaolei.hibernate.pojos.People" table="people"> 
  6.         <!-- 復(fù)合主鍵使用composite-id標(biāo)簽 --> 
  7.         <composite-id> 
  8.             <!-- key-property標(biāo)簽表示哪一些屬性對(duì)應(yīng)復(fù)合主鍵 --> 
  9.             <key-property name="id" column="id" type="string"></key-property> 
  10.             <key-property name="name" column="name" type="string"></key-property> 
  11.         </composite-id> 
  12.  
  13.         <property name="age" column="age" type="integer"></property> 
  14.     </class> 
  15. </hibernate-mapping> 

Hibernate中使用復(fù)合主鍵時(shí)需要注意一些規(guī)則:

1. 使用復(fù)合主鍵的實(shí)體類必須實(shí)現(xiàn)Serializable接口。必須實(shí)現(xiàn)Serializable接口的原因很簡單,我們查找數(shù)據(jù)的時(shí)候是根據(jù)主鍵查找的。打開Hibernate的幫助文檔我們可以找到get與load方法的聲明形式如下:

Object load(Class theClass,Serializable id)

Object get(Class theClass,Serializable id)

當(dāng)我們查找復(fù)合主鍵類的對(duì)象時(shí),需要傳遞主鍵值給get()或load()方法的id參數(shù),而id參數(shù)只能接收一個(gè)實(shí)現(xiàn)了Serializable接口的對(duì)象。而復(fù)合主鍵類的主鍵不是一個(gè)屬性可以表示的,所以只能先new出復(fù)合主鍵類的實(shí)例(例如:new People()),然后使用主鍵屬性的set方法將主鍵值賦值給主鍵屬性,然后將整個(gè)對(duì)象傳遞給get()或load()方法的id參數(shù),實(shí)現(xiàn)主鍵值的傳遞,所以復(fù)合主鍵的實(shí)體類必須實(shí)現(xiàn)Serializable接口。

2. 使用復(fù)合主鍵的實(shí)體類必須重寫equals和hashCode方法。必須重寫equals和hashCode方法也很好理解。這兩個(gè)方法使用于判斷兩個(gè)對(duì)象 (兩條記錄)是否相等的。為什么要判斷兩個(gè)對(duì)象是否相等呢?因?yàn)閿?shù)據(jù)庫中的任意兩條記錄中的主鍵值是不能相同的,所以我們?cè)诔绦蛑兄灰_保了兩個(gè)對(duì)象的主鍵值不同就可以防止主鍵約束違例的錯(cuò)誤出現(xiàn)。也許這里你會(huì)奇怪為什么不使用復(fù)合主鍵的實(shí)體類不重寫這兩個(gè)方法也沒有主鍵違例的情況出現(xiàn),這是因?yàn)槭褂脝我恢麈I方式,主鍵值是Hibernate來維護(hù)的,它會(huì)確保主鍵不會(huì)重復(fù),而復(fù)合主鍵方式,主鍵值是編程人員自己維護(hù)的,所以必須重寫equals和hashCode方法用于判斷兩個(gè)對(duì)象的主鍵是否相同。

3. 重寫的equals和hashCode方法,只與主鍵屬性有關(guān),普通屬性不要影響這兩個(gè)方法進(jìn)行判斷。這個(gè)原因很簡單,主鍵才能決定一條記錄,其他屬性不能決定一條記錄。

保存測(cè)試:

  1. public class Client  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         Session session = HibernateUtil.getSessionFactory().openSession();  
  6.         Transaction tx = null;  
  7.           
  8.         try 
  9.         {  
  10.             tx = session.beginTransaction();  
  11.               
  12.             People people = new People();  
  13.             /*主鍵值由我們自己維護(hù)*/ 
  14.             people.setId("123456");  
  15.             people.setName("zhangsan");  
  16.             people.setAge(40);  
  17.               
  18.             session.save(people);  
  19.               
  20.             tx.commit();  
  21.         }  
  22.         catch (Exception e)  
  23.         {  
  24.             if(tx != null)  
  25.             {  
  26.                 tx.rollback();  
  27.             }  
  28.               
  29.             e.printStackTrace();  
  30.         }  
  31.         finally 
  32.         {  
  33.             session.close();  
  34.         }  
  35.     }  

看看數(shù)據(jù)庫:

數(shù)據(jù)被正確的插入到數(shù)據(jù)庫中了。

讀取數(shù)據(jù)測(cè)試:

  1. public class Client  
  2. {  
  3.     public static void main(String[] args)  
  4.     {  
  5.         Session session = HibernateUtil.getSessionFactory().openSession();  
  6.         Transaction tx = null;  
  7.           
  8.         try 
  9.         {  
  10.             tx = session.beginTransaction();  
  11.               
  12.             /*查詢復(fù)合主鍵對(duì)象,需要先構(gòu)建主鍵*/ 
  13.             People peoplePrimaryKey = new People();  
  14.             peoplePrimaryKey.setId("123456");  
  15.             peoplePrimaryKey.setName("zhangsan");  
  16.               
  17.             /*然后將構(gòu)建的主鍵值傳入get方法中獲取對(duì)應(yīng)的People對(duì)象*/ 
  18.             People people = (People)session.get(People.class, peoplePrimaryKey);  
  19.               
  20.             System.out.println("people age is:"+people.getAge());  
  21.               
  22.             tx.commit();  
  23.         }  
  24.         catch (Exception e)  
  25.         {  
  26.             if(tx != null)  
  27.             {  
  28.                 tx.rollback();  
  29.             }  
  30.               
  31.             e.printStackTrace();  
  32.         }  
  33.         finally 
  34.         {  
  35.             session.close();  
  36.         }  
  37.     }  

控制臺(tái)輸出:

people age is:40

可以看到數(shù)據(jù)成功的取出了。

 

方式二:將主鍵屬性提取到一個(gè)主鍵類中,實(shí)體類只需包含主鍵類的一個(gè)引用。

主鍵類:

  1. /*必須實(shí)現(xiàn)Serializable接口*/ 
  2. public class PeoplePrimaryKey implements Serializable  
  3. {  
  4.     private static final long serialVersionUID = -1190986010439330142L;  
  5.       
  6.     /*復(fù)合主鍵值*/ 
  7.     private String id;  
  8.     private String name;  
  9.       
  10.     public PeoplePrimaryKey()  
  11.     {  
  12.           
  13.     }  
  14.       
  15.     /*復(fù)合主鍵值的get和set方法*/ 
  16.     public String getId()  
  17.     {  
  18.         return id;  
  19.     }  
  20.  
  21.     public void setId(String id)  
  22.     {  
  23.         this.id = id;  
  24.     }  
  25.  
  26.     public String getName()  
  27.     {  
  28.         return name;  
  29.     }  
  30.  
  31.     public void setName(String name)  
  32.     {  
  33.         this.name = name;  
  34.     }  
  35.  
  36.     @Override 
  37.     public int hashCode()  
  38.     {  
  39.         final int prime = 31;  
  40.         int result = 1;  
  41.         result = prime * result + ((id == null) ? 0 : id.hashCode());  
  42.         result = prime * result + ((name == null) ? 0 : name.hashCode());  
  43.         return result;  
  44.     }  
  45.  
  46.     @Override 
  47.     public boolean equals(Object obj)  
  48.     {  
  49.         if (this == obj)  
  50.             return true;  
  51.         if (obj == null)  
  52.             return false;  
  53.         if (getClass() != obj.getClass())  
  54.             return false;  
  55.         PeoplePrimaryKey other = (PeoplePrimaryKey) obj;  
  56.         if (id == null)  
  57.         {  
  58.             if (other.id != null)  
  59.                 return false;  
  60.         }  
  61.         else if (!id.equals(other.id))  
  62.             return false;  
  63.         if (name == null)  
  64.         {  
  65.             if (other.name != null)  
  66.                 return false;  
  67.         }  
  68.         else if (!name.equals(other.name))  
  69.             return false;  
  70.         return true;  
  71.     }  

實(shí)體類:

  1. public class People  
  2. {  
  3.     /*持有主鍵類的一個(gè)引用,使用該引用作為這個(gè)類的OID*/ 
  4.     private PeoplePrimaryKey peoplePrimaryKey;  
  5.     private int age;  
  6.       
  7.     public People()  
  8.     {  
  9.           
  10.     }  
  11.       
  12.     public PeoplePrimaryKey getPeoplePrimaryKey()  
  13.     {  
  14.         return peoplePrimaryKey;  
  15.     }  
  16.  
  17.     public void setPeoplePrimaryKey(PeoplePrimaryKey peoplePrimaryKey)  
  18.     {  
  19.         this.peoplePrimaryKey = peoplePrimaryKey;  
  20.     }  
  21.  
  22.     public int getAge()  
  23.     {  
  24.         return age;  
  25.     }  
  26.  
  27.     public void setAge(int age)  
  28.     {  
  29.         this.age = age;  
  30.     }  

People.hbm.xml文件稍有一點(diǎn)變動(dòng):

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3.  
  4. <hibernate-mapping> 
  5.     <class name="com.suxiaolei.hibernate.pojos.People" table="people"> 
  6.         <!-- 復(fù)合主鍵使用composite-id標(biāo)簽 --> 
  7.         <!--  
  8.         name - 指定了復(fù)合主鍵對(duì)應(yīng)哪一個(gè)屬性  
  9.         class - 指定了復(fù)合主鍵屬性的類型  
  10.         --> 
  11.         <composite-id name="peoplePrimaryKey" class="com.suxiaolei.hibernate.pojos.PeoplePrimaryKey"> 
  12.             <!-- key-property指定了復(fù)合主鍵由哪些屬性組成 --> 
  13.             <key-property name="id" column="id" type="string"></key-property> 
  14.             <key-property name="name" column="name" type="string"></key-property> 
  15.         </composite-id> 
  16.  
  17.         <property name="age" column="age" type="integer"></property> 
  18.     </class> 
  19. </hibernate-mapping> 

場(chǎng)景測(cè)試與方式一大同小異這里不再舉例了。主鍵類為什么實(shí)現(xiàn)Serializable接口和為什么重寫equals和hashCode方法上面已經(jīng)解釋的很清楚了。

原文鏈接:http://www.cnblogs.com/otomedaybreak/archive/2012/01/25/2329390.html

【編輯推薦】

  1. Hibernate繼承映射
  2. Hibernate事務(wù)與并發(fā)問題處理
  3. 讓Hibernate顯示SQL語句的綁定參數(shù)值
  4. hibernate中MySQL自增字段的映射描述
  5. Hibernate+MySQL 中文問題的解決
責(zé)任編輯:林師授 來源: 音①曉的博客
相關(guān)推薦

2009-06-01 12:11:31

hibernatejpa復(fù)合主鍵

2012-03-21 11:43:41

JavaHibernate

2012-02-02 16:13:29

HibernateJava

2009-09-23 09:16:25

Hibernate復(fù)合

2009-09-23 14:23:51

Hibernate主鍵

2009-09-24 10:50:31

Hibernate主鍵

2009-09-23 17:34:18

Hibernate映射

2009-09-25 10:00:47

Hibernate映射

2012-02-03 11:17:33

HibernateJava

2009-09-22 15:10:22

Hibernate映射

2009-09-25 13:33:43

Hibernate主鍵

2009-06-29 08:56:49

Hibernate主鍵生成主鍵

2011-07-25 18:11:47

SQL Server數(shù)復(fù)合主鍵

2009-09-22 09:31:15

Hibernate主鍵

2009-09-24 13:49:31

Hibernate自增

2009-09-25 09:46:02

Hibernate高級(jí)

2009-09-29 15:58:22

Hibernate映射

2009-09-25 12:59:52

Hibernate映射

2009-09-27 10:02:29

定制Hibernate

2009-09-28 14:54:33

Hibernate映射
點(diǎn)贊
收藏

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