SpringData JPA複合主鍵 的使用

複合主鍵 和 聯合主鍵的區別

複合主鍵 : 一張表中 , 兩個字段 確定一條唯一數據 ;

聯合主鍵 : 表A , 表 B 兩張表 , 通過中間表 , 確定兩張表的對應關係 ;
(中間表三個字段 : id , 表A_id, 表B_id) ; 此時中間表的id 稱爲 聯合主鍵 ;

spring jpa 複合主鍵 的使用

使用場景 : 訂單類的 , 訂單編號 ORDER_NUM + 訂單子項目 INNER_NUM , 兩個字段 組成 複合主鍵 , 確定唯一數據 ;

  • 方式一 : 使用 @Embeddable 註解主鍵類 ; 然後 實體類 繼承自主鍵類 ; (該方式書寫簡潔, 但是不易懂)

1 . 編寫一個複合主鍵類 ; 命名可以在 實體類名後 + PK 用於 區分 主鍵類 ;

@Embeddable // 1. 在複合主鍵的類上,使用註解@Embeddable
public class OrderPK implements Serializable { // 2. 實現Serializable接口(否則會報錯);

    @Column(name = "ORDER_NUM")
    private String orderNum; // 主單號
    @Column(name = "INNER_NUM")
    private String innerNum; // 子項目

    // 3. 無參構造
    //          有默認的public無參數的構造方法(在我這個實例中,我沒有添加有參構造方法,所以採用默認的構造方法)
    //          如果你在實體類裏有有參構造方法,那麼一定要有一個無參構造方法,否則運行的時候會報錯

    // 4. 重寫equals和hashCode方法。
    //          equals方法用於判斷兩個對象是否相同,EntityManger通過find方法來查找Entity時,
    //          是根據equals的返回值來判斷的。
    //          hashCode方法返回當前對象的哈希碼
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof OrderPK)) return false;

        OrderPK orderPK = (OrderPK) o;

        if (orderNum != null ? !orderNum.equals(orderPK.orderNum) : orderPK.orderNum != null) return false;
        return innerNum != null ? innerNum.equals(orderPK.innerNum) : orderPK.innerNum == null;
    }

    @Override
    public int hashCode() {
        int result = orderNum != null ? orderNum.hashCode() : 0;
        result = 31 * result + (innerNum != null ? innerNum.hashCode() : 0);
        return result;
    }

    // 生成 get set toString 此處省略
}

2 . 編寫實體類 , 繼承 主鍵類;

@Entity
@Table(name = "ORDER")
public class Order extends OrderPK {

    // 複合主鍵要用這個註解
    @EmbeddedId
    private OrderPK id;

    // 複合主鍵的兩個字段, 在實體類中,就不用寫了

    @Column(name = "OTHER_FIELD")
    private String otherField; // 其他字段

   // 生成 get set toString 此處省略
}
  • 方式二 : 採用 @IdClass 來註解複合主鍵; ( 推薦 , 複合主鍵字段, 在實體類中, 直接有體現 , 看起來簡單明瞭)
    1 . 編寫一個複合主鍵類;
// @Embeddable
public class OrderPK implements Serializable {

    // @Column(name = "ORDER_NUM")
    private String orderNum; // 主單號

    // @Column(name = "INNER_NUM")
    private String innerNum; // 子項目

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof OrderPK)) return false;

        OrderPK orderPK = (OrderPK) o;

        if (orderNum != null ? !orderNum.equals(orderPK.orderNum) : orderPK.orderNum != null) return false;
        return innerNum != null ? innerNum.equals(orderPK.innerNum) : orderPK.innerNum == null;
    }

    @Override
    public int hashCode() {
        int result = orderNum != null ? orderNum.hashCode() : 0;
        result = 31 * result + (innerNum != null ? innerNum.hashCode() : 0);
        return result;
    }

   // 生成 get set toString 此處省略

}

2 . 編寫實體類

@Entity
@Table(name = "ORDER")
@IdClass(OrderPK.class) // 添加 @IdClass 註解 , 指定 複合主鍵類
public class Order implements Serializable { // 不用再繼承 複合主鍵類

	//  @EmbeddedId
	//  private OrderPK id;

    @Id // 添加複合主鍵標識
    @Column(name = "ORDER_NUM")
    private String orderNum; // 主單號

    @Id // 添加複合主鍵標識
    @Column(name = "INNER_NUM")
    private String innerNum; // 子項目

    @Column(name = "OTHER_FIELD")
    private String otherField; // 其他字段

    // 生成 get set toString 此處省略
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章