首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 註解實現複合主鍵完整指南

     編輯:Java 相關知識

前言

在實體類設計中,有時候單一欄位無法唯一標識一筆資料,必須組合多個欄位才能構成主鍵。例如「CustomerEO」實體,需要同時根據 name 與 email 來查找,只有當兩者值完全相同時,才視為同一實體。本文將詳細說明如何使用 Hibernate 註解(@IdClass)來配置複合主鍵。

步驟一:建立複合主鍵類

首先編寫一個專門的主鍵類 CustomerPK,必須滿足以下條件:

  • 實作 Serializable 介面
  • 提供公用的無參數建構子
  • 覆寫 equals() 與 hashCode() 方法
import java.io.Serializable;

public class CustomerPK implements Serializable {

    public CustomerPK() {}

    public CustomerPK(String name, String email) {
        this.name = name;
        this.email = email;
    }

    private String email;
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }

    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((email == null) ? 0 : email.hashCode());
        result = PRIME * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final CustomerPK other = (CustomerPK) obj;
        if (email == null) {
            if (other.email != null) return false;
        } else if (!email.equals(other.email)) return false;
        if (name == null) {
            if (other.name != null) return false;
        } else if (!name.equals(other.name)) return false;
        return true;
    }
}

關鍵點說明:

  • equals() 用於判斷兩個主鍵物件是否相同,EntityManager 的 find() 方法即依賴此方法。
  • hashCode() 應盡量減少碰撞機率,上述演算法為常見實作方式。

步驟二:在實體類上標註複合主鍵

使用 @IdClass 註解指定主鍵類,並在對應的屬性 getter 方法上加上 @Id:

@Entity
@Table(name = "customer")
@IdClass(CustomerPK.class)
public class CustomerEO implements java.io.Serializable {

    private Integer id;
    public Integer getId() { return this.id; }
    public void setId(Integer id) { this.id = id; }

    private String name;
    @Id
    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    private String email;
    @Id
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

注意事項:

  • @IdClass 的 value 屬性必須指向複合主鍵類(本例為 CustomerPK.class)。
  • 實體類中參與複合主鍵的屬性(name、email)必須在 getter 上標註 @Id,且型別、名稱需與主鍵類一致。

步驟三:使用複合主鍵查詢實體

完成上述設定後,即可透過主鍵物件直接查詢:

CustomerPK cpk = new CustomerPK("Janet", "janetvsfei@yahoo.com.cn");
CustomerEO instance = entityManager.find(CustomerEO.class, cpk);

這樣即能精確取得符合複合主鍵條件的實體物件。

總結

採用 @IdClass 實現複合主鍵的優點在於:主鍵類與實體類分離,符合單一職責原則;且主鍵類可重複使用於多個實體。只要遵循「實作 Serializable、提供無參建構子、正確覆寫 equals/hashCode」三原則,即可輕鬆應對複合主鍵場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved