📄 inheritance.html
字号:
... </subclass> <subclass name="ChequePayment" discriminator-value="CHEQUE"> ... </subclass></class></pre><p> 对上述任何一种映射策略而言,指向根类<tt class="literal">Payment</tt>的 关联是使用<tt class="literal"><many-to-one></tt>进行映射的。 </p><pre class="programlisting"><many-to-one name="payment" column="PAYMENT_ID" class="Payment"/></pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="inheritance-tableperconcrete"></a>10.1.5. 每个具体类一张表(Table per concrete class)</h3></div></div><div></div></div><p> 对于“每个具体类一张表”的映射策略,可以采用两种方法。第一种方法是使用 <tt class="literal"><union-subclass></tt>。 </p><pre class="programlisting"><class name="Payment"> <id name="id" type="long" column="PAYMENT_ID"> <generator class="sequence"/> </id> <property name="amount" column="AMOUNT"/> ... <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT"> <property name="creditCardType" column="CCTYPE"/> ... </union-subclass> <union-subclass name="CashPayment" table="CASH_PAYMENT"> ... </union-subclass> <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT"> ... </union-subclass></class></pre><p> 这里涉及三张表。每张表为对应类的所有属性(包括从超类继承的属性)定义相应字段。 </p><p> 这种方式的局限在于,如果一个属性在超类中做了映射,其字段名必须与所有子类 表中定义的相同。(我们可能会在Hibernate的后续发布版本中放宽此限制。) 不允许在联合子类(union subclass)的继承层次中使用标识生成器策略(identity generator strategy), 实际上, 主键的种子(primary key seed)不得不为同一继承层次中的全部被联合子类所共用. </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="inheritance-tableperconcreate-polymorphism"></a>10.1.6. Table per concrete class, using implicit polymorphism</h3></div><div><h3 class="title"><a name="inheritance-tableperconcreate-polymorphism"></a>10.1.6. Table per concrete class, using implicit polymorphism</h3></div></div><div></div></div><p> 另一种可供选择的方法是采用隐式多态: </p><pre class="programlisting"><class name="CreditCardPayment" table="CREDIT_PAYMENT"> <id name="id" type="long" column="CREDIT_PAYMENT_ID"> <generator class="native"/> </id> <property name="amount" column="CREDIT_AMOUNT"/> ...</class><class name="CashPayment" table="CASH_PAYMENT"> <id name="id" type="long" column="CASH_PAYMENT_ID"> <generator class="native"/> </id> <property name="amount" column="CASH_AMOUNT"/> ...</class><class name="ChequePayment" table="CHEQUE_PAYMENT"> <id name="id" type="long" column="CHEQUE_PAYMENT_ID"> <generator class="native"/> </id> <property name="amount" column="CHEQUE_AMOUNT"/> ...</class></pre><p> 注意,我们没有在任何地方明确的提及接口<tt class="literal">Payment</tt>。同时注意 <tt class="literal">Payment</tt>的属性在每个子类中都进行了映射。如果你想避免重复, 可以考虑使用XML实体(例如:位于<tt class="literal">DOCTYPE</tt>声明内的 <tt class="literal">[ <!ENTITY allproperties SYSTEM "allproperties.xml"> ]</tt> 和映射中的<tt class="literal">&allproperties;</tt>)。 </p><p> 这种方法的缺陷在于,在Hibernate执行多态查询时(polymorphic queries)无法生成带 <tt class="literal">UNION</tt>的SQL语句。 </p><p> 对于这种映射策略而言,通常用<tt class="literal"><any></tt>来实现到 <tt class="literal">Payment</tt>的多态关联映射。 </p><pre class="programlisting"><any name="payment" meta-type="string" id-type="long"> <meta-value value="CREDIT" class="CreditCardPayment"/> <meta-value value="CASH" class="CashPayment"/> <meta-value value="CHEQUE" class="ChequePayment"/> <column name="PAYMENT_CLASS"/> <column name="PAYMENT_ID"/></any></pre></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="inheritace-mixingpolymorphism"></a>10.1.7. 隐式多态和其他继承映射混合使用</h3></div></div><div></div></div><p> 对这一映射还有一点需要注意。因为每个子类都在各自独立的元素<tt class="literal"><class></tt> 中映射(并且<tt class="literal">Payment</tt>只是一个接口),每个子类可以很容易的成为另一 个继承体系中的一部分!(你仍然可以对接口<tt class="literal">Payment</tt>使用多态查询。) </p><pre class="programlisting"><class name="CreditCardPayment" table="CREDIT_PAYMENT"> <id name="id" type="long" column="CREDIT_PAYMENT_ID"> <generator class="native"/> </id> <discriminator column="CREDIT_CARD" type="string"/> <property name="amount" column="CREDIT_AMOUNT"/> ... <subclass name="MasterCardPayment" discriminator-value="MDC"/> <subclass name="VisaPayment" discriminator-value="VISA"/></class><class name="NonelectronicTransaction" table="NONELECTRONIC_TXN"> <id name="id" type="long" column="TXN_ID"> <generator class="native"/> </id> ... <joined-subclass name="CashPayment" table="CASH_PAYMENT"> <key column="PAYMENT_ID"/> <property name="amount" column="CASH_AMOUNT"/> ... </joined-subclass> <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"> <key column="PAYMENT_ID"/> <property name="amount" column="CHEQUE_AMOUNT"/> ... </joined-subclass></class></pre><p> 我们还是没有明确的提到<tt class="literal">Payment</tt>。 如果我们针对接口<tt class="literal">Payment</tt>执行查询 ——如<tt class="literal">from Payment</tt>—— Hibernate 自动返回<tt class="literal">CreditCardPayment</tt>(和它的子类,因为 它们也实现了接口<tt class="literal">Payment</tt>)、 <tt class="literal">CashPayment</tt>和<tt class="literal">Chequepayment</tt>的实例, 但不返回<tt class="literal">NonelectronicTransaction</tt>的实例。 </p></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="inheritance-limitations"></a>10.2. 限制</h2></div></div><div></div></div><p> 对“每个具体类映射一张表”(table per concrete-class)的映射策略而言,隐式多态的 方式有一定的限制。而<tt class="literal"><union-subclass></tt>映射的限制则没有那 么严格。 </p><p> 下面表格中列出了在Hibernte中“每个具体类一张表”的策略和隐式多态的限制。 </p><div class="table"><a name="d0e8645"></a><p class="title"><b>表 10.1. 继承映射特性(Features of inheritance mappings) </b></p><table summary="继承映射特性(Features of inheritance mappings) " border="1"><colgroup><col align="left"><col align="left"><col align="left"><col align="left"><col align="left"><col align="left"><col align="left"><col align="left"></colgroup><thead><tr><th align="left">继承策略(Inheritance strategy)</th><th align="left">多态多对一</th><th align="left">多态一对一</th><th align="left">多态一对多</th><th align="left">多态多对多</th><th align="left">多态 <tt class="literal">load()/get()</tt></th><th align="left">多态查询</th><th align="left">多态连接(join)</th><th align="left">外连接(Outer join)抓取</th></tr></thead><tbody><tr><td align="left">每个类分层结构一张表</td><td align="left"><tt class="literal"><many-to-one></tt></td><td align="left"><tt class="literal"><one-to-one></tt></td><td align="left"><tt class="literal"><one-to-many></tt></td><td align="left"><tt class="literal"><many-to-many></tt></td><td align="left"><tt class="literal">s.get(Payment.class, id)</tt></td><td align="left"><tt class="literal">from Payment p</tt></td><td align="left"><tt class="literal">from Order o join o.payment p</tt></td><td align="left"><span class="emphasis"><em>支持</em></span></td></tr><tr><td align="left">每个子类一张表</td><td align="left"><tt class="literal"><many-to-one></tt></td><td align="left"><tt class="literal"><one-to-one></tt></td><td align="left"><tt class="literal"><one-to-many></tt></td><td align="left"><tt class="literal"><many-to-many></tt></td><td align="left"><tt class="literal">s.get(Payment.class, id)</tt></td><td align="left"><tt class="literal">from Payment p</tt></td><td align="left"><tt class="literal">from Order o join o.payment p</tt></td><td align="left"><span class="emphasis"><em>支持</em></span></td></tr><tr><td align="left">每个具体类一张表(union-subclass)</td><td align="left"><tt class="literal"><many-to-one></tt></td><td align="left"><tt class="literal"><one-to-one></tt></td><td align="left"><tt class="literal"><one-to-many></tt> (仅对于<tt class="literal">inverse="true"</tt>的情况)</td><td align="left"><tt class="literal"><many-to-many></tt></td><td align="left"><tt class="literal">s.get(Payment.class, id)</tt></td><td align="left"><tt class="literal">from Payment p</tt></td><td align="left"><tt class="literal">from Order o join o.payment p</tt></td><td align="left"><span class="emphasis"><em>支持</em></span></td></tr><tr><td align="left">每个具体类一张表(隐式多态)</td><td align="left"><tt class="literal"><any></tt></td><td align="left"><span class="emphasis"><em>不支持</em></span></td><td align="left"><span class="emphasis"><em>不支持</em></span></td><td align="left"><tt class="literal"><many-to-any></tt></td><td align="left"><tt class="literal">s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</tt></td><td align="left"><tt class="literal">from Payment p</tt></td><td align="left"><span class="emphasis"><em>不支持</em></span></td><td align="left"><span class="emphasis"><em>不支持</em></span></td></tr></tbody></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="components.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="objectstate.html">下一页</a></td></tr><tr><td width="40%" align="left" valign="top">第 9 章 组件(Component)映射 </td><td width="20%" align="center"><a accesskey="h" href="index.html">起始页</a></td><td width="40%" align="right" valign="top"> 第 11 章 与对象共事</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -