📄 components.html
字号:
<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>第 9 章 组件(Component)映射</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="associations.html" title="第 8 章 关联关系映射"><link rel="next" href="inheritance.html" title="第 10 章 继承映射(Inheritance Mappings)"></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">第 9 章 组件(Component)映射</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="associations.html">上一页</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="inheritance.html">下一页</a></td></tr></table><hr></div><div class="chapter" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title"><a name="components"></a>第 9 章 组件(Component)映射</h2></div></div><div></div></div><p> <span class="emphasis"><em>Component</em></span>这个概念在Hibernate中几处不同的地方为了不同的目的被重复使用. </p><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="components-dependentobjects"></a>9.1. 依赖对象(Dependent objects)</h2></div></div><div></div></div><p> Component是一个被包含的对象,它作为值类型被持久化,而非一个被引用的实体。“component(组件)”这一术语指的是面向对象的合成概念(而并不是系统构架层次上的组件的概念)举个例子, 你可以对人(Person)如以下这样来建模: </p><pre class="programlisting">public class Person { private java.util.Date birthday; private Name name; private String key; public String getKey() { return key; } private void setKey(String key) { this.key=key; } public java.util.Date getBirthday() { return birthday; } public void setBirthday(java.util.Date birthday) { this.birthday = birthday; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } ...... ......}</pre><pre class="programlisting">public class Name { char initial; String first; String last; public String getFirst() { return first; } void setFirst(String first) { this.first = first; } public String getLast() { return last; } void setLast(String last) { this.last = last; } public char getInitial() { return initial; } void setInitial(char initial) { this.initial = initial; }}</pre><p> 现在,<tt class="literal">姓名(Name)</tt>是作为<tt class="literal">人(Person)</tt>的一个组成部分。需要注意的是:需要对<tt class="literal">姓名</tt> 的持久化属性定义getter和setter方法,但是不需要实现任何的接口或申明标识符字段。 </p><p> 以下是这个例子的Hibernate映射文件: </p><pre class="programlisting"><class name="eg.Person" table="person"> <id name="Key" column="pid" type="string"> <generator class="uuid.hex"/> </id> <property name="birthday" type="date"/> <component name="Name" class="eg.Name"> <!-- class attribute optional --> <property name="initial"/> <property name="first"/> <property name="last"/> </component></class></pre><p> 人员(Person)表中将包括<tt class="literal">pid</tt>, <tt class="literal">birthday</tt>, <tt class="literal">initial</tt>, <tt class="literal">first</tt>和 <tt class="literal">last</tt>等字段。 </p><p> 就像所有的值类型一样, Component不支持共享引用。 换句话说,两个人可能重名,但是两个person对象应该包含两个独立的name对象,只不过是具有“同样”的值。 Component的值为空从语义学上来讲是<span class="emphasis"><em>专有的(ad hoc)</em></span>。 每当 重新加载一个包含组件的对象,如果component的所有字段为空,那么将Hibernate将假定整个component为 空。对于绝大多数目的,这样假定是没有问题的。 </p><p> Component的属性可以是Hibernate类型(包括Collections, many-to-one 关联, 以及其它Component 等等)。嵌套Component不应该作为特殊的应用被考虑(Nested components should not be considered an exotic usage)。 Hibernate趋向于支持设计细致(fine-grained)的对象模型。 </p><p> <tt class="literal"><component></tt> 元素还允许有 <tt class="literal"><parent></tt>子元素 ,用来表明component类中的一个属性返回包含它的实体的引用。 </p><pre class="programlisting"><class name="eg.Person" table="person"> <id name="Key" column="pid" type="string"> <generator class="uuid.hex"/> </id> <property name="birthday" type="date"/> <component name="Name" class="eg.Name" unique="true">> <parent name="namedPerson"/> <!-- reference back to the Person --> <property name="initial"/> <property name="first"/> <property name="last"/> </component></class></pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="components-incollections"></a>9.2. 在集合中出现的依赖对象</h2></div></div><div></div></div><p> Hibernate支持component的集合(例如: 一个元素是“姓名”这种类型的数组)。 你可以使用<tt class="literal"><composite-element></tt>标签替代<tt class="literal"><element></tt>标签来定义你的component集合。 </p><pre class="programlisting"><set name="someNames" table="some_names" lazy="true"> <key column="id"/> <composite-element class="eg.Name"> <!-- class attribute required --> <property name="initial"/> <property name="first"/> <property name="last"/> </composite-element></set></pre><p> 注意,如果你决定定义一个元素是联合元素的<tt class="literal">Set</tt>,正确地实现<tt class="literal">equals()</tt>和<tt class="literal">hashCode()</tt>是非常重要的。 </p><p> 组合元素可以包含component但是不能包含集合。如果你的组合元素自身包含component, 必须使用<tt class="literal"><nested-composite-element></tt>标签。这是一个相当特殊的案例 - 组合元素的集合自身可以包含component。 这个时候你就应该考虑一下使用one-to-many关联是否会更恰当。 尝试对这个组合元素重新建模为一个实体-但是需要注意的是,虽然Java模型和重新建模前 是一样的,关系模型和持久性语义上仍然存在轻微的区别。 </p><p> 请注意如果你使用<tt class="literal"><set></tt>标签,一个组合元素的映射不支持可能为空的属性. 当删除对象时, Hibernate必须使用每一个字段的来确定一条记录(在组合元素表中,没有单个的关键字段), 如果有为null的字段,这样做就不可能了。你必须作出一个选择,要么在组合元素中使用不能为空的属性, 要么选择使用<tt class="literal"><list></tt>, <tt class="literal"><map></tt>,<tt class="literal"><bag></tt> 或者 <tt class="literal"><idbag></tt>而不是 <tt class="literal"><set></tt>。 </p><p> 组合元素有个特别的案例,是组合元素可以包含一个<tt class="literal"><many-to-one></tt> 元素。类似这样的映射允许你映射一个many-to-mang关联表作为组合元素额外的字段。(A mapping like this allows you to map extra columns of a many-to-many association table to the composite element class.) 接下来的的例子是从<tt class="literal">Order</tt>到<tt class="literal">Item</tt>的一个多对多的关联关系,而 <tt class="literal">purchaseDate</tt>, <tt class="literal">price</tt> 和 <tt class="literal">quantity</tt> 是<tt class="literal">Item</tt>的关联属性。 </p><pre class="programlisting"><class name="eg.Order" .... >
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -