Teacher(1) ↔ Class(1) 雙向外鍵:
Teacher.classId → Class.id
Class.teacherId → Teacher.id
雙方主鍵均為自增,插入一方後需另一方 ID 回填,形成循環依賴。
| 方案 | 步驟 | 優點 | 缺點 |
|---|---|---|---|
| 補償 UPDATE | 1. INSERT Teacher → get id 2. INSERT Class(teacherId) → get id 3. UPDATE Teacher SET classId=? | 邏輯直觀,符合現有表結構 | 兩次寫入,事務管理稍繁瑣 |
| 單向外鍵 + 視圖 | 僅在 Class 保留 teacherId,Teacher 去掉 classId。查詢時用 View 關聯 | 插入簡單,無循環 | 需修改表結構,視圖更新有限制 |
| 聯合主鍵/共享主鍵 | Class.id 同時作為 PK 和 FK 指向 Teacher.id | 天然一對一,無額外外鍵列 | 業務語義綁定,擴展性差 |
若表結構不可變,**補償 UPDATE** 是唯一選擇,建議在服務層用事務包裹:
@Transactional
public void addTeacherAndClass(Teacher t, Class c) {
teacherDao.insert(t); // 回填 t.id
c.setTeacherId(t.getId());
classDao.insert(c); // 回填 c.id
t.setClassId(c.getId());
teacherDao.update(t); // 補充 classId
}
mappedBy),數據庫層面單向外鍵足矣。