hibernate注解方式实现复合主键

32 篇文章 0 订阅

有时一个实体的主键可能同时为多个,例如同样是之前使用的“CustomerEO”实体,需要通过name和email来查找指定实体,当且仅当name和email的值完全相同时,才认为是相同的实体对象。要配置这样的复合主键,步骤如以下所示。

(1)编写一个复合主键的类CustomerPK,代码如下。

CustomerPK.java

[java]  view plain copy
  1. import java.io.Serializable;  
  2.   
  3.    
  4.   
  5. public class CustomerPK implements Serializable {  
  6.   
  7.    
  8.   
  9.          public CustomerPK() {  
  10.   
  11.    
  12.   
  13.          }  
  14.   
  15.    
  16.   
  17.          public CustomerPK(String name, String email) {  
  18.   
  19.                    this.name = name;  
  20.   
  21.                    this.email = email;  
  22.   
  23.          }  
  24.   
  25.    
  26.   
  27.          private String email;  
  28.   
  29.    
  30.   
  31.          public String getEmail() {  
  32.   
  33.                    return email;  
  34.   
  35.          }  
  36.   
  37.    
  38.   
  39.          public void setEmail(String email) {  
  40.   
  41.                    this.email = email;  
  42.   
  43.          }  
  44.   
  45.    
  46.   
  47.          private String name;  
  48.   
  49.    
  50.   
  51.          public String getName() {  
  52.   
  53.                    return name;  
  54.   
  55.          }  
  56.   
  57.    
  58.   
  59.          public void setName(String name) {  
  60.   
  61.                    this.name = name;  
  62.   
  63.          }  
  64.   
  65.    
  66.   
  67.          @Override  
  68.   
  69.          public int hashCode() {  
  70.   
  71.                    final int PRIME = 31;  
  72.   
  73.                    int result = 1;  
  74.   
  75.                    result = PRIME * result + ((email == null) ? 0 : email.hashCode());  
  76.   
  77.                    result = PRIME * result + ((name == null) ? 0 : name.hashCode());  
  78.   
  79.                    return result;  
  80.   
  81.          }  
  82.   
  83.    
  84.   
  85.          @Override  
  86.   
  87.          public boolean equals(Object obj) {  
  88.   
  89.                    if (this == obj)  
  90.   
  91.                             return true;  
  92.   
  93.                    if (obj == null)  
  94.   
  95.                             return false;  
  96.   
  97.                    if (getClass() != obj.getClass())  
  98.   
  99.                             return false;  
  100.   
  101.                    final CustomerPK other = (CustomerPK) obj;  
  102.   
  103.                    if (email == null) {  
  104.   
  105.                             if (other.email != null)  
  106.   
  107.                                      return false;  
  108.   
  109.                    } else if (!email.equals(other.email))  
  110.   
  111.                             return false;  
  112.   
  113.                    if (name == null) {  
  114.   
  115.                             if (other.name != null)  
  116.   
  117.                                      return false;  
  118.   
  119.                    } else if (!name.equals(other.name))  
  120.   
  121.                             return false;  
  122.   
  123.                    return true;  
  124.   
  125.          }  
  126.   
  127.    
  128.   
  129. }  

 

作为符合主键类,要满足以下几点要求。

l         必须实现Serializable接口。

l         必须有默认的public无参数的构造方法。

l         必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。本例中,只有对象的name和email值完全相同时或同一个对象时则返回true,否则返回false。hashCode方法返回当前对象的哈希码,生成的hashCode相同的概率越小越好,算法可以进行优化。

(2)通过@IdClass注释在实体中标注复合主键,实体代码如下。

 

[java]  view plain copy
  1. @Entity  
  2.   
  3. @Table(name = "customer")  
  4.   
  5. @IdClass(CustomerPK.class)  
  6.   
  7. public class CustomerEO implements java.io.Serializable {  
  8.   
  9.    
  10.   
  11.          private Integer id;  
  12.   
  13.    
  14.   
  15.          public Integer getId() {  
  16.   
  17.                    return this.id;  
  18.   
  19.          }  
  20.   
  21.    
  22.   
  23.          public void setId(Integer id) {  
  24.   
  25.                    this.id = id;  
  26.   
  27.          }  
  28.   
  29.            
  30.   
  31.          private String name;  
  32.   
  33.    
  34.   
  35. @Id  
  36.   
  37.          public String getName() {  
  38.   
  39.                    return this.name;  
  40.   
  41.          }  
  42.   
  43.    
  44.   
  45.          public void setName(String name) {  
  46.   
  47.                    this.name = name;  
  48.   
  49.          }  
  50.   
  51.            
  52.   
  53.          private String email;  
  54.   
  55. @Id  
  56.   
  57.          public String getEmail() {  
  58.   
  59.                    return email;  
  60.   
  61.          }  
  62.   
  63.    
  64.   
  65.          public void setEmail(String email) {  
  66.   
  67.                    this.email = email;  
  68.   
  69.          }  
  70.   
  71. }  

 

标注复合主键时需要注意以下几个问题。

l         @IdClass标注用于标注实体所使用主键规则的类。它的定义如下所示。

@Target({TYPE}) @Retention(RUNTIME)

public @interface IdClass {

Class value();

}

属性Class表示符合主键所使用的类,本例中使用CustomerPK这个复合主键类。

l         在实体中同时标注主键的属性。本例中在email和name的getter方法前标注@Id,表示符合主键使用这两个属性。

(3)这样定义实体的复合主键后,通过以下代码便可以获得指定的实体对象:

    CustomerPK cpk = new CustomerPK("Janet","janetvsfei@yahoo.com.cn");

    CustomerEO instance = entityManager.find(CustomerEO.class, cpk);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值