📄 components.html
字号:
</p><p> 组合元素有个特别的用法是它可以包含一个<tt class="literal"><many-to-one></tt>元素。类似这样的映射允许你将一个many-to-many关联表映射为组合元素的集合。(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> 。 </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> 当然,当你定义Item时,你无法引用这些purchase,因此你无法实现双向关联查询。记住组件是值类型,并且不允许共享引用。某一个特定的<tt class="literal">Purchase</tt> 可以放在<tt class="literal">Order</tt>的集合中,但它不能同时被<tt class="literal">Item</tt>所引用。 </p><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>8.3. 组件作为Map的索引(Components as Map indices )</h2></div></div><div></div></div><p> <tt class="literal"><composite-map-key></tt>元素允许你映射一个组件类作为一个<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>8.4. 组件作为联合标识符(Components as composite identifiers)</h2></div></div><div></div></div><p> 你可以使用一个组件作为一个实体类的标识符。 你的组件类必须满足以下要求: </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> <span class="emphasis"><em>注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。</em></span> </p><p> 你不能使用一个<tt class="literal">IdentifierGenerator</tt>产生组合关键字。一个应用程序必须分配它自己的标识符。 </p><p> 使用<tt class="literal"><composite-id></tt> 标签(并且内嵌<tt class="literal"><key-property></tt>元素)代替通常的<tt class="literal"><id></tt>标签。比如,<tt class="literal">OrderLine</tt>类具有一个主键,这个主键依赖于<tt class="literal">Order</tt>的(联合)主键。 </p><pre class="programlisting"><class name="OrderLine"> <composite-id name="id" class="OrderLineId"> <key-property name="lineId"/> <key-property name="orderId"/> <key-property name="customerId"/> </composite-id> <property name="name"/> <many-to-one name="order" class="Order" insert="false" update="false"> <column name="orderId"/> <column name="customerId"/> </many-to-one> .... </class></pre><p> 现在,任何指向<tt class="literal">OrderLine</tt>的外键都是复合的。在你的映射文件中,必须为其他类也这样声明。例如,一个指向<tt class="literal">OrderLine</tt>的关联可能被这样映射: </p><pre class="programlisting"><many-to-one name="orderLine" class="OrderLine"><!-- the "class" attribute is optional, as usual --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/></many-to-one></pre><p> (注意在各个地方<tt class="literal"><column></tt>标签都是<tt class="literal">column</tt>属性的替代写法。) </p><p> 指向<tt class="literal">OrderLine</tt>的<tt class="literal">多对多</tt>关联也使用联合外键: </p><pre class="programlisting"><set name="undeliveredOrderLines"> <key column name="warehouseId"/> <many-to-many class="OrderLine"> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </many-to-many></set></pre><p> 在<tt class="literal">Order</tt>中,<tt class="literal">OrderLine</tt>的集合则是这样: </p><pre class="programlisting"><set name="orderLines" inverse="true"> <key> <column name="orderId"/> <column name="customerId"/> </key> <one-to-many class="OrderLine"/></set></pre><p> (与通常一样,<tt class="literal"><one-to-many></tt>元素不声明任何列.) </p><p> 假若<tt class="literal">OrderLine</tt>本身拥有一个集合,它也具有组合外键。 </p><pre class="programlisting"><class name="OrderLine"> .... .... <list name="deliveryAttempts"> <key> <!-- a collection inherits the composite key type --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </key> <list-index column="attemptId" base="1"/> <composite-element class="DeliveryAttempt"> ... </composite-element> </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>8.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" type="string"/> <property name="bar" column="BAR" type="integer"/> <many-to-one name="baz" class="Baz" column="BAZ_ID"/></dynamic-component></pre><p> 从<tt class="literal"><dynamic-component></tt>映射的语义上来讲,它和<tt class="literal"><component></tt>是相同的。 这种映射类型的优点在于通过修改映射文件,就可以具有在部署时检测真实属性的能力。利用一个DOM解析器,也可以在程序运行时操作映射文件。 更好的是,你可以通过<tt class="literal">Configuration</tt>对象来访问(或者修改)Hibernate的运行时元模型。 </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="associations.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">第 7 章 关联关系映射 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 9 章 继承映射(Inheritance Mappings)</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -