📄 associations.html
字号:
<one-to-many class="Person"/> </set></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><p> 如果你使用<tt class="literal">List</tt>(或者其他有序集合类),你需要设置外键对应的<tt class="literal">key</tt>列为 <tt class="literal">not null</tt>,让Hibernate来从集合端管理关联,维护每个元素的索引(通过设置<tt class="literal">update="false"</tt> and <tt class="literal">insert="false"</tt>来对另一端反向操作)。 </p><pre class="programlisting"><class name="Person"> <id name="id"/> ... <many-to-one name="address" column="addressId" not-null="true" insert="false" update="false"/></class><class name="Address"> <id name="id"/> ... <list name="people"> <key column="addressId" not-null="true"/> <list-index column="peopleIdx"/> <one-to-many class="Person"/> </list></class></pre><p> 假若集合映射的<tt class="literal"><key></tt>元素对应的底层外键字段是<tt class="literal">NOT NULL</tt>的,那么为这一key元素定义<tt class="literal">not-null="true"</tt>是很重要的。不要仅仅为可能的嵌套<tt class="literal"><column></tt>元素定义<tt class="literal">not-null="true"</tt>,<tt class="literal"><key></tt>元素也是需要的。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="assoc-bidirectional-121"></a>7.4.2. 一对一(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> <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> <one-to-one name="person" property-ref="address"/></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> <one-to-one name="address"/></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><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="assoc-bidirectional-join"></a>7.5. 使用连接表的双向关联(Bidirectional 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-bidirectional-join-12m"></a>7.5.1. 一对多(one to many) /多对一( many to one)</h3></div></div><div></div></div><p> <span class="emphasis"><em>基于连接表的双向一对多关联</em></span>。注意<tt class="literal">inverse="true"</tt>可以出现在关联的任意一端,即collection端或者join端。 </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> <join table="PersonAddress" inverse="true" optional="true"> <key column="addressId"/> <many-to-one name="person" column="personId" not-null="true"/> </join></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 )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-bidirectional-join-121"></a>7.5.2. 一对一(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> <join table="PersonAddress" optional="true" inverse="true"> <key column="addressId" unique="true"/> <many-to-one name="person" column="personId" not-null="true" unique="true"/> </join></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-bidirectional-join-m2m"></a>7.5.3. 多对多(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> <set name="people" inverse="true" table="PersonAddress"> <key column="addressId"/> <many-to-many column="personId" class="Person"/> </set></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-complex"></a>7.6. 更复杂的关联映射</h2></div></div><div></div></div><p> 更复杂的关联连接<span class="emphasis"><em>极为</em></span>罕见。 通过在映射文档中嵌入SQL片断,Hibernate也可以处理更为复杂的情况。比如,假若包含历史帐户数据的表定义了<tt class="literal">accountNumber</tt>, <tt class="literal">effectiveEndDate</tt> 和<tt class="literal">effectiveStartDate</tt>字段,按照下面映射: </p><pre class="programlisting"><properties name="currentAccountKey"> <property name="accountNumber" type="string" not-null="true"/> <property name="currentAccount" type="boolean"> <formula>case when effectiveEndDate is null then 1 else 0 end</formula> </property></properties><property name="effectiveEndDate" type="date"/><property name="effectiveStateDate" type="date" not-null="true"/></pre><p> 那么我们可以对<span class="emphasis"><em>目前(current)</em></span>实例(其<tt class="literal">effectiveEndDate</tt>为null)使用这样的关联映射: </p><pre class="programlisting"><many-to-one name="currentAccountInfo" property-ref="currentAccountKey" class="AccountInfo"> <column name="accountNumber"/> <formula>'1'</formula></many-to-one></pre><p> 更复杂的例子,假想<tt class="literal">Employee</tt>和<tt class="literal">Organization</tt>之间的关联是通过一个<tt class="literal">Employment</tt>中间表维护的,而中间表中填充了很多历史雇员数据。那“雇员的<span class="emphasis"><em>最新</em></span>雇主”这个关联(最新雇主就是<tt class="literal">startDate</tt>最后的那个)可以这样映射: </p><pre class="programlisting"><join> <key column="employeeId"/> <subselect> select employeeId, orgId from Employments group by orgId having startDate = max(startDate) </subselect> <many-to-one name="mostRecentEmployer" class="Organization" column="orgId"/></join></pre><p> 使用这一功能时可以充满创意,但通常更加实用的是用HQL或条件查询来处理这些情形。 </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="collections.html">上一页</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">上一级</a></td><td width="40%" align="right"> <a accesskey="n" href="components.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 6 章 集合类(Collections)映射 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 8 章 组件(Component)映射</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -