Hibernate 中的關聯映射是 ORM 核心功能之一。本文針對「一對一」關係,透過「學生-老師」實例,完整展示註解與 XML 兩種映射配置方式,幫助開發者理解雙向一對一的建模細節。
假設系統中有 student 與 teacher 兩張表,業務規則為:一個學生僅對應一位老師,一位老師也僅指導一名學生。這是典型的一對一雙向關聯,雙方均持有對方的引用。
package com.entity;
public class Teacher {
private int id;
private String tname;
private Student student; // 關聯屬性
// 主鍵生成策略:native(跨資料庫自動選擇)
public int getId() { return id; }
public void setId(int id) { this.id = id; }
// 一對一映射:cascade="all" 表示級聯儲存/刪除/更新
public Student getStudent() { return student; }
public void setStudent(Student student) { this.student = student; }
public String getTname() { return tname; }
public void setTname(String tname) { this.tname = tname; }
}
package com.entity;
public class Student {
private int id;
private String sname;
private Teacher teacher; // 關聯屬性
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getSname() { return sname; }
public void setSname(String sname) { this.sname = sname; }
public Teacher getTeacher() { return teacher; }
public void setTeacher(Teacher teacher) { this.teacher = teacher; }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Student" table="student">
<id name="id" column="id" type="int">
<generator class="native"/>
</id>
<property name="sname" column="sname"/>
<!-- 一對一雙向關聯:constrained="false" 表示不強制外鍵約束 -->
<one-to-one name="teacher" class="com.entity.Teacher"
cascade="all" outer-join="auto" constrained="false"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Teacher" table="teacher">
<id name="id" column="id" type="int">
<generator class="native"/>
</id>
<one-to-one name="student" class="com.entity.Student"
cascade="all" outer-join="auto" constrained="false"/>
<property name="tname" column="tname"/>
</class>
</hibernate-mapping>
student.setTeacher(t); t.setStudent(student);),否則可能導致資料不一致。foreign 生成器;本範例使用 native 為各自獨立主鍵,較為靈活。one-to-one 預設不支援 proxy 延遲載入(除非使用 constrained="true"),建議根據業務需求權衡。一對一映射雖較少見,但在「擴充表」、「詳情表」等場景極為實用。掌握 <one-to-one> 的 cascade、constrained、outer-join 等屬性,能讓你精準控制關聯行為,避免級聯操作帶來的副作用。