複合主鍵由多欄位組合唯一標識記錄,又稱自然鍵或業務鍵。優點是業務語義明確;缺點是設計編碼較複雜,且將數據庫模型綁定特定業務域,遷移困難。常見於遺留系統整合或業務強制要求場景。
BillingAddress (使用 @Embeddable)@Embeddable
public class BillingAddress implements Serializable {
private String street;
private String city;
public BillingAddress() {}
public BillingAddress(String street, String city) {
this.street = street; this.city = city;
}
// Getter/Setter 省略
}
關鍵點:實現 Serializable、標註 @Embeddable 使其可嵌入其他實體。
PurchaseOrder (使用 @IdClass)@Entity
@Table(name = "PURCHASE_ORDERS")
@IdClass(BillingAddress.class)
public class PurchaseOrder {
@Id
@AttributeOverrides({
@AttributeOverride(name = "street", column = @Column(name = "STREET")),
@AttributeOverride(name = "city", column = @Column(name = "CITY"))
})
private String street;
private String city;
private String itemName;
public PurchaseOrder() {}
public PurchaseOrder(BillingAddress addr) {
this.street = addr.getStreet();
this.city = addr.getCity();
}
// Getter/Setter 省略
}
註解解析:
@IdClass 指定複合鍵類@Id + @AttributeOverrides 將嵌入類屬性映射為表主鍵欄位CREATE TABLE PURCHASE_ORDERS (
street VARCHAR(255) NOT NULL,
city VARCHAR(255) NOT NULL,
itemName VARCHAR(255),
PRIMARY KEY (street, city)
);
EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
PurchaseOrder order = new PurchaseOrder(new BillingAddress("Broad Street", "Boston"));
order.setItemName("My new computer");
em.persist(order);
tx.commit();
em.close();
執行後數據庫記錄:
STREET | CITY | ITEMNAME
Broad Street | Boston | My new computer
@Embeddable + @IdClass 是 JPA 標準實現方式