3.6.2 每张表一个类层次

来源:互联网 发布:手机视频合成软件 编辑:程序博客网 时间:2024/05/22 05:04

 

另外一种做法就是一张表映射到整个类层次上面。这张表的列和类层次中的所有属性相对应。具体的子类代表的行有discrimator列来决定。具体可以参看3.8。

在性能和简易性上这种映射策略都是值得考虑的。同时它也是表示多态的最好方法,不论是多态查询还是非多态查询都能工作的很好,而且容易实现。它可以尽可能的不使用连接和联合,schema的改变也变得更加的直观。

有一个主要的问题:表示属性的列必须是可以为null的。如果子类定义了几个非null的属性,那么从数据完整性的角度来考虑的话,NOT NULL约束的丢失会成为一个严重的问题。

在hibernate中,我们使用<subclass>属性来指定表与类层次之间的映射关系。具体可以参见列表3.8。

(1)在类层次结构中的基类BusinessDetails被映射到表BUSINESS_DETAILS。

(2)我们需要一个特殊的列来区分持久类:discriminator。这并不是一个持久类的属性;它只是在Hibrenate内部来使用。列名是BILLING_DETAIL_TYPE,至于值的设定,在本例中为'CC'或者'BA'。Hibernate会自动设置和取回discriminator的值。

(3)基类的属性仍然用<property>属性来映射。

(4)每个子类都有属于自身的<subclass>元素。子类的属性被映射到BILLING_DETAILS表。请记住非NULL的值是不允许的,因为CreditCard实例不能拥有一个null的bankSwift属性。

<subclass>可以包含其他<subclass>元素,知道整个类层次被映射到表格。一个<subclass>元素不能包含<joined-subclass>元素。在这一点上,映射策略是无法被改变的。

Hibernate将会使用如下的SQL语句来查询BillingDetails类:

select BILLING_DETAILS_ID, BILLING_DETAILS_TYPE,OWNER,.....CREDIT_CARD_TYPE, from BILLING_DETAILS where CREATED=?

为了查询CreditCard子类,Hibernate将会使用在discriminator使用查询条件:

select BILLING_DETAILS_ID, CREDIT_CARD_TYPE, CREDIT_CARD_EXP_MONTH, … from BILLING_DETAILS where BILLING_DETAILS_TYPE='CC' and CREDTED=?

 

原创粉丝点击