`
feng_gladys
  • 浏览: 7783 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java Persistence With Hibernate Chatper 5

阅读更多

Chapter 5Inheritance and custom types<o:p></o:p>

5.1 Mapping class inheritance<o:p></o:p>

       最简单的映射策略是“一个持久类对应一张表”,但在面向对象继承体系中,这种策略就不足够,SQL支持是‘has a’关系,而java支持‘has a’和‘is a’,SQL数据库并不支持类型继承,这就需要我们寻找新的策略来解决继承问题:<o:p></o:p>

       一般有4中策略:<o:p></o:p>

Table per concrete class with implicit polymorphism—Use no explicit inheritance mapping, and default runtime polymorphic behavior.<o:p></o:p>

Table per concrete class—Discard polymorphism and inheritance relationships<o:p></o:p>

completely from the SQL schema.<o:p></o:p>

Table per class hierarchy—Enable polymorphism by denormalizing the SQL<o:p></o:p>

schema, and utilize a type discriminator column that holds type information.<o:p></o:p>

Table per subclass—Represent is a (inheritance) relationships as has a (foreign<o:p></o:p>

key) relationships.<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">5.1.1</st1:chsdate> Table per concrete class with implicit polymorphism<o:p></o:p>

      Every concrete subclass is mapping to a table, the solution is so straightforward,<o:p></o:p>

But there are several problems with this approach.<o:p></o:p>

       1, we can’t get a foreign key to super class to make sure the polymorphism in model domain, <o:p></o:p>

       or when there is a “many to one” relation from another model to the Billing; for example ,:User n:1 Billing,  we must deal with the both concrete subclasses tables.<o:p></o:p>

       2, query problems:<o:p></o:p>

       A SQL query against the super class must be executed several SQL query, one for each concrete subclass.<o:p></o:p>

       3, Conceptual problem:<o:p></o:p>

       Different columns of subclass tables share the same semantics: <o:p></o:p>

       When a property of super class changed, we must update all the corresponding columns in different subclass tables, it’s such a terrible job…<o:p></o:p>

<o:p> </o:p>

       With so many problems, so this approach is recommend only for the top lever of class hierarchy, where the polymorphism isn’t usually required and when the modification of the super class in future is unlikely<o:p></o:p>

<o:p> </o:p>

<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">5.1.2</st1:chsdate> Table per concrete class with unions<o:p></o:p>

       In this situation, we still have two tables with duplicate column in bath.<o:p></o:p>

<hibernate-mapping><o:p></o:p></hibernate-mapping>

<class><o:p></o:p></class>

<

<class<o:p></o:p>

name="BillingDetails"<o:p></o:p>

abstract="true"> // an abstract class (interface ) must be declared as “true”<o:p></o:p>

                //otherwise there needs a single table for superclass<o:p></o:p>

<id<o:p></o:p>

name="id"<o:p></o:p>

column="BILLING_DETAILS_ID"<o:p></o:p>

type="long">  // the id property is shared by all subclass<o:p></o:p>

<generator class="native"/><o:p></o:p>

</id><o:p></o:p>

<property<o:p></o:p>

name="name"<o:p></o:p>

column="OWNER"<o:p></o:p>

type="string"/> // superclass’s properties are shared by all subclasses<o:p></o:p>

<o:p> </o:p>

...<o:p></o:p>

<union-subclass<o:p></o:p>

name="CreditCard" table="CREDIT_CARD"><o:p></o:p>

<property name="number" column=”NUMBER”/><o:p></o:p>

<property name="expMonth" column="EXP_MONTH"/><o:p></o:p>

<property name="expYear" column="EXP_YEAR"/><o:p></o:p>

</union-subclass><o:p></o:p>

<union-subclass<o:p></o:p>

name="BankAccount" table="BANK_ACCOUNT"><o:p></o:p>

...<o:p></o:p>

</class><o:p></o:p>

</hibernate-mapping>

<o:p></o:p>

With this strategy, we still need two tables and duplicate columns in tables, but the first advantage is that we don’t need to declare duplicate mapping for tables, <o:p></o:p>

<o:p> </o:p>

If the superclass is a concrete class, you should need an additional table for holding the instances of the class.<o:p></o:p>

Be sure that from the view of tables, we can’t see any relation between them.  <o:p></o:p>

<o:p> </o:p>

The second advantage is that we can do a better query now:<o:p></o:p>

select<o:p></o:p>

    BILLING_DETAILS_ID, OWNER,<o:p></o:p>

    NUMBER, EXP_MONTH, EXP_YEAR,<o:p></o:p>

    ACCOUNT, BANKNAME, SWIFT<o:p></o:p>

    CLAZZ_<o:p></o:p>

from<o:p></o:p>

( select<o:p></o:p>

    BILLING_DETAILS_ID, OWNER,<o:p></o:p>

    NUMBER, EXP_MONTH, EXP_YEAR,<o:p></o:p>

    null as ACCOUNT, null as BANKNAME, null as SWIFT,<o:p></o:p>

    1 as CLAZZ_<o:p></o:p>

from<o:p></o:p>

    CREDIT_CARD<o:p></o:p>

union<o:p></o:p>

    select<o:p></o:p>

        BILLING_DETAILS_ID, OWNER,<o:p></o:p>

        null as NUMBER, null as EXP_MONTH, null as EXP_YEAR, ...<o:p></o:p>

        ACCOUNT, BANKNAME, SWIFT,<o:p></o:p>

        2 as CLAZZ_<o:p></o:p>

    from<o:p></o:p>

    BANK_ACCOUNT<o:p></o:p>

)<o:p></o:p>

 将表中没有,但其他类中有的字段设为null,最后统一查询所有的字段,Hibernate本身能判断是到底要实例化为哪个具体的子类或父类。<o:p></o:p>

<o:p> </o:p>

The third advantage is that we can handle the domain polymorphism relations now, <o:p></o:p>

Just make relations to the superclass.<o:p></o:p>

<o:p> </o:p>

<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">5.1.3</st1:chsdate> Table per class hierarchy<o:p></o:p>

In this strategy, all the properties in the class hierarchy are mapping to a single table,<o:p></o:p>

The concrete subclass is represented by a column is identified by the value of the discriminator.<o:p></o:p>

<!----><!----><!----><o:p></o:p>

This approach is so simple and straightforward, it supports the polymorphism very well.<o:p></o:p>

But to be noticed, the columns in the table must be declared as nullable, the second is that this approach may not satisfy the normalization, <o:p></o:p>

Mapping in Hibernate XML files:<o:p></o:p>

 


<hibernate-mapping><o:p></o:p>

<class<o:p></o:p>

    name="BillingDetails"<o:p></o:p>

    table="BILLING_DETAILS"> // the class hierarchy is mapped to a single table<o:p></o:p>

   <id<o:p></o:p>

        name="id"<o:p></o:p>

        column="BILLING_DETAILS_ID"<o:p></o:p>

        type="long"><o:p></o:p>

        <generator class="native"/><o:p></o:p>

   </id><o:p></o:p>

    <discriminator<o:p></o:p>

        column="BILLING_DETAILS_TYPE"<o:p></o:p>

        type="string"/> // the column to distinguish the concrete subclasses, Using                         // by  hibernate  internally <o:p></o:p>

   <property<o:p></o:p>

        name="owner"<o:p></o:p>

        column="OWNER"<o:p></o:p>

        type="string"/><o:p></o:p>

            ...<o:p></o:p>

   <subclass            // subclass mapping, must declare the discriminator value<o:p></o:p>

        name="CreditCard"<o:p></o:p>

        discriminator-value="CC"><o:p></o:p>

       <property name="number" column="CC_NUMBER"/><o:p></o:p>

       <property name="expMonth" column="CC_EXP_MONTH"/><o:p></o:p>

       <property name="expYear" column="CC_EXP_YEAR"/><o:p></o:p>

    </subclass><o:p></o:p>

    <subclass<o:p></o:p>

        name=”BankAccount”<o:p></o:p>

        discriminator-value=”BA”><o:p></o:p>

        ...<o:p></o:p>

</class>


Hibernate generates the following SQL when querying the BillingDetails<o:p></o:p>

class:<o:p></o:p>

select<o:p></o:p>

    BILLING_DETAILS_ID, BILLING_DETAILS_TYPE, OWNER,<o:p></o:p>

    CC_NUMBER, CC_EXP_MONTH, ..., BA_ACCOUNT, BA_BANKNAME, ...<o:p></o:p>

from BILLING_DETAILS<o:p></o:p>

To query the CreditCard subclass, Hibernate adds a restriction on the discriminator<o:p></o:p>

column:<o:p></o:p>

select BILLING_DETAILS_ID, OWNER, CC_NUMBER, CC_EXP_MONTH, ...<o:p></o:p>

    from BILLING_DETAILS<o:p></o:p>

    where BILLING_DETAILS_TYPE='CC'<o:p></o:p>

all the detail is managed by hibernate internally.<o:p></o:p>

<o:p> </o:p>

Note: this strategy may be too serious to your database schema design, because it doesn’t satisfy normalizations and guarantee the integrity of the data.<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

<st1:chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">5.1.4</st1:chsdate> Table per subclass<o:p></o:p>

       Every class is mapped to a table in despite of abstract, concrete class or interface, the table only holds the properties in the corresponding class.<o:p></o:p>

       When an object of subclass is persisted, the properties declared in superclass are persisted to a new row of the superclass_table,  only the properties declared in subclass are persisted to a new row of the corresponding subclass table, and the two rows in different tables share the same identity.<o:p></o:p>

<o:p> </o:p>

<!----><!----><!----><o:p></o:p>

Using hibernate <join-subclass> property:<o:p></o:p></join-subclass>

<o:p> </o:p>

<hibernate-mapping><o:p></o:p>

<class<o:p></o:p>

    name="BillingDetails"<o:p></o:p>

    table="BILLING_DETAILS"><o:p></o:p>

    <id<o:p></o:p>

        name="id"<o:p></o:p>

        column="BILLING_DETAILS_ID"<o:p></o:p>

        type="long"><o:p></o:p>

        <generator class="native"/><o:p></o:p>

L.3 Hibernate <joined-subclass> mapping<o:p></o:p>

   </id><o:p></o:p>

   <property<o:p></o:p>

        name="owner"<o:p></o:p>

        column="OWNER"<o:p></o:p>

        type="string"/><o:p></o:p>

        ...<o:p></o:p>

    <joined-subclass<o:p></o:p>

        name="CreditCard"    <o:p></o:p>

        table="CREDIT_CARD"><o:p></o:p>

        <key column="CREDIT_CARD_ID"/> // share the same id with subclass table<o:p></o:p>

<o:p> </o:p>

       <property name="number" column="NUMBER"/><o:p></o:p>

        <property name="expMonth" column="EXP_MONTH"/><o:p></o:p>

        <property name="expYear" column="EXP_YEAR"/><o:p></o:p>

    </joined-subclass><o:p></o:p>

    <joined-subclass<o:p></o:p>

        name="BankAccount"<o:p></o:p>

        table="BANK_ACCOUNT"><o:p></o:p>

        ...<o:p></o:p>

   </class><o:p></o:p>

</hibernate-mapping><o:p></o:p>

This strategy can well support the polymorphism in domain models, but if there is a very complex classes’ hierarchy, this approach will be unacceptable, the cost of query will be a nightmare because every query requires a join cross several tables.

 

<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">5.1.5</st1:chsdate> Mixing inheritance strategies<o:p></o:p>

<o:p> </o:p>

Of course, we can mix the strategies discussed above, for the third strategy, we can add a <join> (the fourth strategy), </join>

<o:p> </o:p>

<hibernate-mapping><o:p></o:p>

<class name="BillingDetails"<o:p></o:p>

table="BILLING_DETAILS"><o:p></o:p>

<id>...</id><o:p></o:p>

<discriminator<o:p></o:p>

column="BILLING_DETAILS_TYPE"<o:p></o:p>

type="string"/><o:p></o:p>

...<o:p></o:p>

<subclass<o:p></o:p>

    name="CreditCard"<o:p></o:p>

    discriminator-value="CC"><o:p></o:p>

    <join table="CREDIT_CARD"><o:p></o:p>

       <key column="CREDIT_CARD_ID"/><o:p></o:p>

      <property name="number" column="CC_NUMBER"/><o:p></o:p>

      <property name="expMonth" column="CC_EXP_MONTH"/><o:p></o:p>

   <property name="expYear" column="CC_EXP_YEAR"/><o:p></o:p>

        ...<o:p></o:p>

   </join><o:p></o:p>

</subclass><o:p></o:p>

<subclass<o:p></o:p>

name="BankAccount"<o:p></o:p>

discriminator-value="BA"><o:p></o:p>

<property name=account" column="BA_ACCOUNT"/><o:p></o:p>

...<o:p></o:p>

</subclass><o:p></o:p>

...<o:p></o:p>

</class><o:p></o:p>

</hibernate-mapping><o:p></o:p>

<o:p></o:p>

<o:p></o:p>

...<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

Also you can add more <join> in you hierarchy, but if the class hierarchy is wide, it will be a problem, some database limit the number of outer_join.</join>

<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">5.1.6</st1:chsdate> Choosing a strategy<o:p></o:p>

<o:p> </o:p>

       Now we know 4 strategies for mapping class hierarchy to database tables, how to choose?

1 if you don’t required polymorphism queries and associations, the second strategy is better(per table concrete class),

2 if you required polymorphism queries and associations, but there are few properties declared in subclass, just use the third strategy(per table a class hierarchy).

3 if you required polymorphism queries and associations, but there are many properties declared in subclass, just use the fourth(table per subclass), or depending on the width and depth of the class hierarchy, considering the second strategy(table per concrete class).

<o:p> </o:p>

Per table a class hierarchy is only for simple problems, for more complex cases, you should consider Per table a subclass, but at the point, you should first ask yourself whether you should redesign your models.

分享到:
评论

相关推荐

    Java Persistence WIth Hibernate 2nd

    Manning出版 Java Persistence With Hibernate 第二版 清晰pdf Hibernate, an open source project that is almost 15 years old. In a recent poll, Hibernate was among the top five tools used by many Java ...

    Java Persistence with Hibernate 1

    Java Persistence with Hibernate

    Java Persistence with Hibernate(2nd) 无水印pdf

    Java Persistence with Hibernate(2nd) 英文无水印pdf 第2版 pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权...

    Java Persistence with Hibernate

    本文将基于《Java Persistence with Hibernate》这一经典著作,深入探讨Hibernate的核心概念和技术细节。 #### 书评摘要与概述 《Java Persistence with Hibernate》被誉为是Hibernate领域的权威指南。本书由项目...

    java persistence with hibernate 2

    java persistence with hibernate 第二部分压缩包

    JavaPersistenceWithHibernate

    《Java Persistence with Hibernate》是一本深入探讨Java领域对象关系映射(ORM)框架Hibernate的专业书籍。这本书详尽地阐述了如何使用Hibernate进行数据持久化,从而帮助开发者在Java应用程序中高效地管理和操作...

    来自Java Persistence With Hibernate的示例

    《Java Persistence with Hibernate示例详解》 在Java开发领域,持久化是不可或缺的一部分,而Hibernate作为Java中最流行的ORM(对象关系映射)框架之一,它极大地简化了数据库操作。本篇将深入探讨“Java ...

    Java Persistence with Hibernate(2nd) epub

    Java Persistence with Hibernate(2nd) 英文epub 第2版 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    Manning - Java Persistence With Hibernate.pdf

    《Java Persistence with Hibernate》是Java开发领域中一本深入探讨Hibernate持久化框架的重要著作。这本书由Christian Bauer和Gavin King合著,详细阐述了如何利用Hibernate进行数据库操作和对象关系映射(ORM)。 ...

    Java Persistence with Hibernate(2nd) mobi

    Java Persistence with Hibernate(2nd) 英文mobi 第2版 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    Java Persistence with Hibernate, 2nd Edition

    《Java Persistence with Hibernate, 2nd Edition》是关于Java领域持久化技术的一本经典著作,主要聚焦于Hibernate框架的应用和深入理解。这本书详尽地介绍了如何利用Hibernate来处理Java应用程序中的对象关系映射...

    JAVA persistence with hibernate

    hibernate bible by Gavin king Nothing more

    java persistence with hibernate3

    java persistence with hibernate第三部分

    Java Persistence with Hibernate01

    Java Persistence with Hibernate(英文版)part1(共两部分)

    Java Persistence with Hibernate02

    Java Persistence with Hibernate(英文版)part2(共两部分)

    Java+Persistence+with+Hibernate

    《Java Persistence with Hibernate》是Java开发领域中一本深入探讨数据持久化技术的重要书籍,主要聚焦于使用Hibernate框架来实现对象关系映射(ORM)。Hibernate是一个流行的开源Java库,它简化了数据库操作,允许...

Global site tag (gtag.js) - Google Analytics