📄 components.html
字号:
<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" .... > .... <set name="purchasedItems" table="purchase_items" lazy="true"> <key column="order_id"> <composite-element class="eg.Purchase"> <property name="purchaseDate"/> <property name="price"/> <property name="quantity"/> <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional --> </composite-element> </set></class></pre><p>即使三重或多重管理都是可能的:</p><pre class="programlisting"><class name="eg.Order" .... > .... <set name="purchasedItems" table="purchase_items" lazy="true"> <key column="order_id"> <composite-element class="eg.OrderLine"> <many-to-one name="purchaseDetails" class="eg.Purchase"/> <many-to-one name="item" class="eg.Item"/> </composite-element> </set></class></pre><p> 在查询中,组合元素使用的语法是和关联到其他实体的语法一样的。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="components-asmapindex"></a>7.3. 组件作为Map的索引(Components as Map indices )</h2></div></div><div></div></div><p> <tt class="literal"><composite-index></tt>元素允许你映射一个Component类作为<tt class="literal">Map</tt>的key, 但是你必须确定你正确的在这个类中重写了<tt class="literal">hashCode()</tt> 和 <tt class="literal">equals()</tt>方法。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="components-compositeid"></a>7.4. 组件作为联合标识符(Components as composite identifiers)</h2></div></div><div></div></div><p> 你可以使用一个component作为一个实体类的标识符。 你的component类必须满足以下要求: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 它必须实现<tt class="literal">java.io.Serializable</tt>接口 </p></li><li><p> 它必须重新实现<tt class="literal">equals()</tt>和<tt class="literal">hashCode()</tt>方法, 始终和组合关键字在数据库中的概念保持一致 </p></li></ul></div><p> 你不能使用一个<tt class="literal">IdentifierGenerator</tt>产生组合关键字。作为替代应用程序必 须分配它自己的标识符. </p><p> 既然联合标识符必须在对象存储之前被分配,我们就不能使用标识符的<tt class="literal">unsaved-value</tt>来把刚刚新建的实例和在先前的session保存的实例区分开来。 </p><p> 如果你希望使用<tt class="literal">saveOrUpdate()</tt>或者级联保存/更新(cascading save / update),你应该实现 <tt class="literal">Interceptor.isUnsaved()</tt>。使用<tt class="literal"><composite-id></tt> 标签(它和<tt class="literal"><component></tt>标签有同样的属性和元素)代替<tt class="literal"><id></tt>标签。 下面有个联合标识符类的定义: </p><pre class="programlisting"><class name="eg.Foo" table"FOOS"> <composite-id name="compId" class="eg.FooCompositeID"> <key-property name="string"/> <key-property name="short"/> <key-property name="date" column="date_" type="date"/> </composite-id> <property name="name"/> ....</class></pre><p> 这时候,任何到<tt class="literal">FOOS</tt>的外键也同样是联合的, 在你其他类的映射文件中也必须同样定义。 一个到<tt class="literal">Foo</tt>的定义应该像以下这样: </p><pre class="programlisting"><many-to-one name="foo" class="eg.Foo"><!-- the "class" attribute is optional, as usual --> <column name="foo_string"/> <column name="foo_short"/> <column name="foo_date"/></many-to-one></pre><p> 新的 <tt class="literal"><column></tt> 标签同样被用于包含多个字段的自定义类型(This new <tt class="literal">column</tt>tag is also used by multi-column custom types)。 事实上在各个地方它都是一个可选的字段属性。要定义一个元素是<tt class="literal">Foo</tt>的集合类,要这样写: </p><pre class="programlisting"><set name="foos"> <key column="owner_id"/> <many-to-many class="eg.Foo"> <column name="foo_string"/> <column name="foo_short"/> <column name="foo_date"/> </many-to-many></set></pre><p> 另一方面,<tt class="literal"><one-to-many></tt>元素通常不定义字段. </p><p> 如果 <tt class="literal">Foo</tt> 自己包含集合, 那么他们也需要使用联合外键。 </p><pre class="programlisting"><class name="eg.Foo"> .... .... <set name="dates" lazy="true"> <key> <!-- a collection inherits the composite key type --> <column name="foo_string"/> <column name="foo_short"/> <column name="foo_date"/> </key> <element column="foo_date" type="date"/> </set></class></pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="components-dynamic"></a>7.5. 动态组件 (Dynamic components)</h2></div></div><div></div></div><p> 你甚至可以映射<tt class="literal">Map</tt>类型的属性: </p><pre class="programlisting"><dynamic-component name="userAttributes"> <property name="foo" column="FOO"/> <property name="bar" column="BAR"/> <many-to-one name="baz" class="eg.Baz" column="BAZ"/></dynamic-component></pre><p> 从<tt class="literal"><dynamic-component></tt>映射的语义上来讲,它和<tt class="literal"><component></tt>是相同的。 这种映射类型的优点在于通过修改映射文件,就可以具有在部署时检测真实属性的能力.(利用一个DOM解析器, 是有可能在运行时刻操作映射文件的。) </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="inheritance.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 章 继承映射(Inheritance Mappings)</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -