Hibernate 註解提供豐富的關聯映射註解,支援單向、雙向、主鍵關聯、外鍵關聯、中間表關聯等多種資料庫模型。本文系統整理 @OneToOne、@ManyToOne 常見配置與生成的 DDL。
關聯方使用 @OneToOne + @PrimaryKeyJoinColumn,雙方共用同一主鍵值。
// A 端
@OneToOne
@PrimaryKeyJoinColumn
private B b;
生成 DDL:
create table A (id integer not null auto_increment, aname varchar(255), primary key (id))
create table B (id integer not null auto_increment, bname varchar(255), primary key (id))
alter table A add constraint FK_A_B foreign key (id) references B (id)
關聯方加 @JoinColumn 指定外鍵欄位名。
@OneToOne
@JoinColumn(name = "b_id") // 指定 FK 欄位名
private B b;
若省略 @JoinColumn,預設欄位名為 屬性名_id (如 b_id)。
關聯方 (Owning Side) 維護外鍵,被關聯方用 mappedBy 指向關聯方屬性名。
// A 端 (Owning Side)
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "b")
private B b;
// B 端 (Inverse Side)
@OneToOne(mappedBy = "b")
private A a;
關鍵: 若 B 端缺少 mappedBy,Hibernate 會在 B 表額外產生 a_id 外鍵,形成兩個獨立 FK。
使用 referencedColumnName 指向被關聯表的唯一鍵 (需加 unique=true)。
@OneToOne
@JoinColumn(name = "b_bname", referencedColumnName = "bname")
private B b;
生成 DDL 會在 B 表的 bname 加 unique 約束,A 表 FK 指向 bname。
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(
name = "centert",
joinColumns = @JoinColumn(name = "aid"),
inverseJoinColumns = @JoinColumn(name = "bid")
)
private B b;
生成獨立中間表 centert,含 aid、bid 兩個 FK。
語法與 OneToOne 類似,差異在語意 (多方對一)。
若一對多雙向關聯中,一的一方 (List/Set) 未加 mappedBy,Hibernate 會產生額外中間表 (如 B_A) 而非在多方表加外鍵。
屬性型別可為介面,實作類由 targetEntity 指定:
private I i;
@ManyToOne(targetEntity = B.class)
public I getI() { return i; }
掌握 @JoinColumn、mappedBy、@JoinTable、referencedColumnName 等註解組合,即可精準對應各種資料庫關聯模型,避免多餘欄位或中間表產生。