📄 associations.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 7 章 关联关系映射</title><link rel="stylesheet" href="../shared/css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.65.1"><link rel="home" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="up" href="index.html" title="HIBERNATE - 符合Java习惯的关系数据库持久化"><link rel="previous" href="collections.html" title="第 6 章 集合类(Collections)映射"><link rel="next" href="components.html" title="第 8 章 组件(Component)映射"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">第 7 章 关联关系映射</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="collections.html">上一页</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="components.html">下一页</a></td></tr></table><hr></div><div class="chapter" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title"><a name="associations"></a>第 7 章 关联关系映射</h2></div></div><div></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="assoc-intro"></a>7.1. 介绍</h2></div></div><div></div></div><p> 关联关系映射通常情况是最难配置正确的。在这个部分中,我们从单向关系映射开始,然后考虑双向关系映射,由浅至深讲述一遍典型的案例。在所有的例子中,我们都使用 <tt class="literal">Person</tt>和<tt class="literal">Address</tt>。 </p><p> 我们根据映射关系是否涉及连接表以及多样性来划分关联类型。 </p><p> 在传统的数据建模中,允许为Null值的外键被认为是一种不好的实践,因此我们所有的例子中都使用不允许为Null的外键。这并不是Hibernate的要求,即使你删除掉不允许为Null的约束,Hibernate映射一样可以工作的很好。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="assoc-unidirectional"></a>7.2. 单向关联(Unidirectional associations)</h2></div></div><div></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-m21"></a>7.2.1. 多对一(many to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>单向many-to-one关联</em></span>是最常见的单向关联关系。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key, addressId bigint not null )create table Address ( addressId bigint not null primary key ) </pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-121"></a>7.2.2. 一对一(one to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于外键关联的单向一对一关联</em></span>和<span class="emphasis"><em>单向多对一关联</em></span>几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" unique="true" not-null="true"/></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key, addressId bigint not null unique )create table Address ( addressId bigint not null primary key ) </pre><p> <span class="emphasis"><em>基于主键关联的单向一对一关联</em></span>通常使用一个特定的id生成器。(请注意,在这个例子中我们掉换了关联的方向。) </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id></class><class name="Address"> <id name="id" column="personId"> <generator class="foreign"> <param name="property">person</param> </generator> </id> <one-to-one name="person" constrained="true"/></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table Address ( personId bigint not null primary key ) </pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-12m"></a>7.2.3. 一对多(one to many)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于外键关联的单向一对多关联</em></span>是一种很少见的情况,并不推荐使用。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table Address ( addressId bigint not null primary key, personId bigint not null ) </pre><p> 我们认为对于这种关联关系最好使用连接表。 </p></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="assoc-unidirectional-join"></a>7.3. 使用连接表的单向关联(Unidirectional associations with join tables)</h2></div></div><div></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-join-12m"></a>7.3.1. 一对多(one to many)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于连接表的单向一对多关联</em></span> 应该优先被采用。请注意,通过指定<tt class="literal">unique="true"</tt>,我们可以把多样性从多对多改变为一对多。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses" table="PersonAddress"> <key column="personId"/> <many-to-many column="addressId" unique="true" class="Address"/> </set></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table PersonAddress ( personId not null, addressId bigint not null primary key )create table Address ( addressId bigint not null primary key ) </pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-join-m21"></a>7.3.2. 多对一(many to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于连接表的单向多对一关联</em></span>在关联关系可选的情况下应用也很普遍。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <join table="PersonAddress" optional="true"> <key column="personId" unique="true"/> <many-to-one name="address" column="addressId" not-null="true"/> </join></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )create table Address ( addressId bigint not null primary key ) </pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-join-121"></a>7.3.3. 一对一(one to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于连接表的单向一对一关联</em></span>非常少见,但也是可行的。 </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <join table="PersonAddress" optional="true"> <key column="personId" unique="true"/> <many-to-one name="address" column="addressId" not-null="true" unique="true"/> </join></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )create table Address ( addressId bigint not null primary key ) </pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-unidirectional-join-m2m"></a>7.3.4. 多对多(many to many)</h3></div></div><div></div></div><p> 最后,还有 <span class="emphasis"><em>单向多对多关联</em></span>. </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses" table="PersonAddress"> <key column="personId"/> <many-to-many column="addressId" class="Address"/> </set></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id></class></pre><pre class="programlisting">create table Person ( personId bigint not null primary key )create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )create table Address ( addressId bigint not null primary key ) </pre></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="assoc-bidirectional"></a>7.4. 双向关联(Bidirectional associations)</h2></div></div><div></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-bidirectional-m21"></a>7.4.1. 一对多(one to many) / 多对一(many to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>双向多对一关联</em></span> 是最常见的关联关系。(这也是标准的父/子关联关系。) </p><pre class="programlisting"><class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/></class><class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> <set name="people" inverse="true"> <key column="addressId"/>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -