承接多對一單向關聯,本文解析一對多單向關聯。核心差異:維護「一指向多」的導航,在「一的一方」配置集合。
public class Classes { // 一的一方,持有集合
private int id;
private String name;
private Set students;
// getter/setter
}
public class Student { // 多的一方,無引用
private int id;
private String name;
// getter/setter
}
| 維度 | 多對一 | 一對多 |
|---|---|---|
| 導航方向 | 多 → 一 | 一 → 多 |
| 外鍵位置 | 多的一方表 | 多的一方表 (相同) |
| 映射標籤 | <many-to-one> | <one-to-many> (在 <set> 內) |
| 資料庫結構 | 相同 | 相同 |
本質:若將集合視為整體,一對多與多對一在資料庫層面完全對稱,僅導航方向不同。
| 表 | 欄位 |
|---|---|
| t_classes | id (PK), name |
| t_student | id (PK), name, classesid (FK) |
<class name="com.zs.hibernate.Classes" table="t_classes">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<set name="students"> <!-- 無 inverse -->
<key column="classesid"/>
<one-to-many class="com.zs.hibernate.Student"/>
</set>
</class>
<class name="com.zs.hibernate.Student" table="t_student">
<id name="id"><generator class="native"/></id>
<property name="name"/>
<!-- 無 many-to-one -->
</class>
classes 引用,Hibernate 不知道屬於哪個 Classes,INSERT 時 classesid 為 null,若資料庫設 NOT NULL 會拋異常cascade="delete",刪除 Classes 會連帶刪除所有 Student,單向無法精細控制在 Student 加入 Classes classes 欄位與 <many-to-one> 映射,即為下篇「一對多雙向關聯」。
@Entity @Table(name="t_classes")
public class Classes {
@OneToMany
@JoinColumn(name="classesid") // 指定外鍵欄位在 Student 表
private Set students = new HashSet<>();
}
@Entity @Table(name="t_student")
public class Student {
// 無註解,純被動
}
下篇講解一對多雙向關聯:加入 many-to-one、設定 inverse="true"、雙向同步最佳實踐。