首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 關聯映射全景圖:從一對一到繼承、組合、復合主鍵完整總結

     編輯:Java 相關知識

Hibernate 關聯映射是 ORM 核心難點。本文系統整理 7 大映射類型:多對一、一對一(主鍵/外鍵/雙向)、一對多(單向/雙向)、多對多(單向/雙向)、三種繼承策略、組合映射、復合主鍵。每類提供對象模型、映射文件、關鍵屬性解析與避坑指南,作為開發查閱速查手冊。

1. 多對一 — 最基礎關聯

場景

User { id, name, Group group }
Group { id, name }

映射

<class name="User" table="t_user">
  <id name="id"><generator class="identity"/></id>
  <property name="name" column="User_name" unique="true"/>
  <many-to-one name="group" column="groupid"/>  // 外鍵在 User 表
</class>

2. 一對一映射 — 三種變體

2.1 主鍵關聯(共享主鍵)

Person { id, name, IdCard idCard }
IdCard { id, cardNo }
// Person 映射
<id name="id">
  <generator class="foreign"><param name="property">idCard</param></generator>
</id>
<one-to-one name="idCard" constrained="true"/>  // constrained=true 級聯保存/刪除

雙向:IdCard 端添加 <one-to-one name="person"/>,默認按主鍵加載。

2.2 外鍵關聯(獨立主鍵 + 唯一外鍵)

Person { id, name, IdCard idCard }
IdCard { id, cardNo }
// Person 映射
<many-to-one name="idCard" class="IdCard" column="idcard_id" unique="true"/>  // 實質是多對一+唯一約束

雙向:IdCard 端需指定 property-ref 指向關聯屬性:

<one-to-one name="person" property-ref="idCard"/>  // 告訴 Hibernate 按 idCard 列加載 Person

3. 一對多映射 — 集合關聯

單向

Class { id, name, Set students }
Student { id, name }
// Class 映射
<set name="students">
  <key column="classid"/>  // 外鍵在 Student 表
  <one-to-many class="Student"/>
</set>

缺陷:Student 端不維護關係,保存時需先 save 學生再 save 班級,且會額外發 UPDATE 更新外鍵。

雙向 — 推薦生產模式

// Class 端
<set name="students" inverse="true">  // 關係由多端維護
  <key column="classid"/>
  <one-to-many class="Student"/>
</set>
// Student 端
<many-to-one name="clazz" column="classid"/>

優勢:inverse="true" 移交關係維護權給多端,避免多餘 UPDATE,保存順序:先班級後學生。

4. 多對多映射 — 中間表

單向

User { id, name, Set roles }
Role { id, name }
// User 映射
<set name="roles" table="t_user_role">
  <key column="userid"/>
  <many-to-many class="Role" column="roleid"/>
</set>

雙向

// Role 端
<set name="users" table="t_user_role">
  <key column="roleid"/>  // 注意:這裡 key 是角色 ID
  <many-to-many class="User" column="userid"/>
</set>

雙向時兩端 table 必須一致,key/column 互為鏡像。

5. 繼承映射 — 三大策略

策略表結構優點缺點映射關鍵
單表 (<subclass>)一張表含所有字段 + discriminator 區分類型查詢最快,無連接字段稀疏,子類字段不能非空discriminator-value 指定類型標識
連表 (<joined-subclass>)父表 + 子表各自表,主鍵關聯規範化,支持非空約束查詢需連接,性能稍弱table 指定子表,<key column="pid"/> 關聯列
聯表 (<union-subclass>)每個具體類一張獨立表,含所有繼承字段查詢快,無連接,支持非空修改父類字段需改多表,主鍵生成策略受限無 discriminator,各表獨立

單表示例

<class name="Animal" table="t_animal">
  <id name="id"><generator class="native"/></id>
  <discriminator column="type" type="string"/>
  <property name="name"/> <property name="sex"/>
  <subclass name="Pig" discriminator-value="P"><property name="weight"/></subclass>
  <subclass name="Bird" discriminator-value="B"><property name="height"/></subclass>
</class>

6. 組合映射 — 值類型嵌入

Component 無 OID,非獨立實體,生命周期綁定宿主實體。

User { id, name, Contact contact }
Contact { email, address, zipcode, contactTel }  // 無 id
// 映射
<component name="contact">
  <property name="email"/>
  <property name="address"/>
  <property name="zipcode"/>
  <property name="contactTel"/>
</component>

同一 Contact 類可在多實體中復用(User、Employee 等)。

7. 復合主鍵映射

將復合鍵屬性封裝為單獨類,必須:

  1. 實現 Serializable
  2. 重寫 equals() 和 hashCode()
// SC 實體:學生-課程關係,主鍵 (sno, cno)
<class name="SC" table="t_sc">
  <composite-id name="scpk" class="SCPK">
    <key-property name="sno"/>
    <key-property name="cno"/>
  </composite-id>
  <property name="sname"/> <property name="cname"/>
</class>

關鍵屬性速查卡

屬性作用常用值
inverse關係維護權移交true(一對多雙向/多對多雙向)
cascade級聯操作save-update, delete, all, delete-orphan
lazy延遲加載true/false/extra/proxy
fetch抓取策略select, join, subselect
constrained一對一主鍵關聯級聯true(外鍵約束+級聯)
property-ref指定關聯屬性一對一外鍵雙向必需
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved