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

Hibernate 3 學習筆記(十一):複合主鍵兩種實現方式

     編輯:Java 相關知識

資料表:雙欄位主鍵

CREATE TABLE user (
    name VARCHAR(100) NOT NULL,
    phone VARCHAR(50) NOT NULL,
    age INT,
    PRIMARY KEY (name, phone)
);

方式一:複合主鍵欄位直接放在實體類別

實體類別需實作 Serializable、equals、hashCode

public class User implements Serializable {
    private String name;
    private String phone;
    private Integer age;
    // getter/setter ...

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof User)) return false;
        User other = (User) obj;
        return new EqualsBuilder()
            .append(this.name, other.name)
            .append(this.phone, other.phone)
            .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder()
            .append(this.name)
            .append(this.phone)
            .toHashCode();
    }
}
使用 Apache Commons Lang EqualsBuilder/HashCodeBuilder 簡化實作,避免手寫錯誤。

映射檔:<composite-id>

<class name="com.hb3.pack_03.model.User" table="user">
    <composite-id>
        <key-property name="name" column="name" type="string"/>
        <key-property name="phone" column="phone" type="string"/>
    </composite-id>
    <property name="age" column="age" type="integer"/>
</class>

操作:主鍵即實體本身

User user = new User();
user.setName("shenbin");
user.setPhone("0970123456");
user.setAge(28);
session.save(user);

// 載入需傳入完整實體作為主鍵
user = (User) session.load(User.class, user);

方式二:複合主鍵提取為獨立 PK 類別

PK 類別

public class UserPK implements Serializable {
    private String name;
    private String phone;
    // getter/setter + equals/hashCode (同上)
}

實體類別持有 PK 物件

public class User implements Serializable {
    private UserPK userPK;
    private Integer age;
    // getter/setter ...
}

映射檔:<composite-id name="userPK" class="UserPK">

<class name="com.hb3.pack_04.model.User" table="user">
    <composite-id name="userPK" class="com.hb3.pack_04.model.UserPK" unsaved-value="any">
        <key-property name="name" column="name" type="string"/>
        <key-property name="phone" column="phone" type="string"/>
    </composite-id>
    <property name="age" column="age" type="integer"/>
</class>
  • unsaved-value="any":Hibernate 總視為新物件(因無單一 ID 判斷),配合 save() 使用。

操作:以 PK 物件載入

UserPK pk = new UserPK();
pk.setName("shenbin");
pk.setPhone("0970123456");

User user = (User) session.load(User.class, pk);

兩種方式比較

維度方式一:內嵌欄位方式二:獨立 PK 類別
程式碼簡潔度實體類別較大職責分離,PK 可重用
序列化/傳遞需傳整個實體可只傳 PK 物件(輕量)
映射複雜度較簡單稍多一個類別映射
適用場景簡單複合鍵、單一實體使用複合鍵被多實體共享、需獨立傳遞 PK

重要提醒

  1. equals/hashCode 必須正確實作,否則 Session 快取、Set/Map 運作會出錯。
  2. 複合主鍵**不支援自動生成策略**,應用程式需自行賦值。
  3. 關聯映射時,外鍵需包含所有複合鍵欄位,映射用 <key-many-to-one> 或多個 <key-property>。
  4. 儲存後**必須呼叫 tx.commit()** 才會持久化到資料庫。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved