基於業務需求,您會需要使用兩個欄位來作複合主鍵,例如在User資料表中,您也許會使用"name"與"phone"兩個欄位來定義複合主鍵。
假設您這麼建立User表格:
CREATE TABLE user ( name VARCHAR(100) NOT NULL, phone VARCHAR(50) NOT NULL, age INT, PRIMARY KEY(name, phone) );
在表格中,"name"與"age"被定義為複合主鍵,在映射時,您可以讓User類別直接帶有"name"與"age"這兩個屬性,而 Hibernate要求複合主鍵類別要實作Serializable介面,並定義equals()與hashCode()方法:
package onlyfun.caterpillar;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder;
// 複合主鍵類的對應類別必須實作Serializable介面 public class User implements Serializable { private String name; private String phone; private Integer age; public User() { }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; } // 必須重新定義equals()與hashCode() public boolean equals(Object obj) { if(obj == this) { return true; } if(!(obj instanceof User)) { return false; } User user = (User) obj; return new EqualsBuilder() .append(this.name, user.getName()) .append(this.phone, user.getPhone()) .isEquals(); } public int hashCode() { return new HashCodeBuilder() .append(this.name) .append(this.phone) .toHashCode(); } } equals()與hashCode()方法被用作兩筆不同資料的識別依據;接著您可以使用在映射文件中定義複合主鍵與物件的屬性對應:
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "">
column="name" type="java.lang.String"/> column="phone" type="java.lang.String"/>
在儲存資料方面,複合主鍵的儲存沒什麼區別,現在的問題在於如何依據複合主鍵來查詢資料,例如使用load()方法,您可以創建一個User實例,並設定複合主鍵對應的屬性,接著再透過load()查詢對應的資料,例如:
User user = new User(); user.setName("bush"); user.setPhone("0970123456"); Session session = sessionFactory.openSession(); // 以實例設定複合主鍵並載入對應的資料 user = (User) session.load(User.class, user); System.out.println(user.getAge() + "\t" + user.getName() + "\t" + user.getPhone()); session.close();
|
|
可以將主鍵的資訊獨立為一個類別,例如:
package onlyfun.caterpillar;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder;
public class UserPK implements Serializable { private String name; private String phone;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; } public boolean equals(Object obj) { if(obj == this) { return true; } if(!(obj instanceof User)) { return false; } UserPK pk = (UserPK) obj; return new EqualsBuilder() .append(this.name, pk.getName()) .append(this.phone, pk.getPhone()) .isEquals(); } public int hashCode() { return new HashCodeBuilder() .append(this.name) .append(this.phone) .toHashCode(); } }
現在User類別的主鍵資訊被分離出來了,例如:
package onlyfun.caterpillar;
import java.io.Serializable;
public class User implements Serializable { private UserPK userPK; // 主鍵 private Integer age; public User() {}
public UserPK getUserPK() { return userPK; }
public void setUserPK(UserPK userPK) { this.userPK = userPK; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; } } 在映射文件方面,需要指定主鍵類的資訊,例如:
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "">
class="onlyfun.caterpillar.UserPK" unsaved-value="any"> column="name" type="java.lang.String"/> column="phone" type="java.lang.String"/>
在查詢資料時,必須指定主鍵資訊,例如:
UserPK pk = new UserPK(); pk.setName("bush"); pk.setPhone("0970123456"); Session session = sessionFactory.openSession(); // 以主鍵類實例設定複合主鍵並載入對應的資料 User user = (User) session.load(User.class, pk); System.out.println(user.getAge() + "\t" + user.getUserPK().getName() + "\t" + user.getUserPK().getPhone()); session.close();
|
|
阅读(1597) | 评论(1) | 转发(0) |