节 1.01 每个带有联合的具体类一张表 – union-class
<!-- 注:抽象的超类或者接口必须声明为 abstract ,否则超类实例需要一张单独表 -->
< class name = "hibernate.hierarchical.BillingDetails" abstract = "true" >
< union-subclass name = "hibernate.hierarchical.CreditCard" table = "CREDIT_CARD" >
< property name = "number" column = "NUMBER" />
< property name = "expMonth" column = "EXP_MONTH" />
< property name = "expYear" column = "EXP_YEAR" />
</ union-subclass >
< union-subclass name = "hibernate.hierarchical.BankAccount" table = "BANK_ACCOUNT" >
< property name = "account" column = "ACCOUNT" />
< property name = "bankname" column = "BANKNAME" />
< property name = "swift" column = "SWIFT" />
</ union-subclass >
</ class >
public class BillingDetails { private Long id ; private String owner ;}
public class BankAccount extends BillingDetails {
private String account ; private String bankname ; private String swift ;}
public class CreditCard extends BillingDetails {
private String number ; private String expMonth ; private String expYear ;}
查询 BillingDetails 时生成的 SQL 如下:
Select BILLING_DETAIL_ID,OWNER… FROM
(
Select BILLING_DETAIL_ID_OWNER,NUMBER,EXP_MONTH,EXMP_YEAR,null as ACCOUNT,null AS BANKNAME,null as SWIFT 1 as CLAZZ_
FROM CREDIT_CARD
UNION
Select BILLING_DETAIL_ID_OWNER,null as NUMBER,null as EXP_MONTH,null as EXP_YEAR,ACCOUNT,BANKNAME,SWIFT,2 as CLAZZ_
FROM BANK_ACCOUNT
)
这样使用的效率最高
节 1.02 每个类层次结构一张表 – SubClass
注:
1、 在表设计时添加辨别标志 (BILLING_DETAILS_TYPE) 用于在持久化类之间区分不同对象。
2、 在列名称设计上需要加前缀(比如 CC/BA )等,用于让 Hibernate 自动识别不同对象。
< class name = "hibernate.hierarchical.BillingDetails" table = "Billing_Details" >
< property name = "owner" column = "OWNER" type = "string" />
<!-- 添加一个辨别标志以便在持久化类之间进行区分 -->
< discriminator column = "BILLING_DETAILS_TYPE" type = "string" />
< subclass name = "hibernate.hierarchical.CreditCard" discriminator-value = "CC" >
< property name = "number" column = "CC_NUMBER" />
< property name = "expMonth" column = "CC_EXP_MONTH" />
< property name = "expYear" column = "CC_EXP_YEAR" />
</ subclass >
< subclass name = "hibernate.hierarchical.BankAccount" discriminator-value = "BA" >
< property name = "account" column = "BA_ACCOUNT" />
< property name = "bankname" column = "BA_BANKNAME" />
< property name = "swift" column = "BA_SWIFT" />
</ subclass >
</ class >
public class BillingDetails { private Long id ; private String owner ;}
public class BankAccount extends BillingDetails {
private String account ; private String bankname ; private String swift ;}
public class CreditCard extends BillingDetails {
private String number ; private String expMonth ; private String expYear ;}
当查询父表 BillingDetails 时将 BILLING_DETAILS 表字段全部查询。
Select BILLING_DETAILS_ID,CC_NUMBER,CC_EXP_MONTH… FROM BILLING_DETAILS
当查询子表 BankAccount/CreditCard 表时通过标识字段进行限制。
Select BILLING_DETAILS_ID,CC_NUMBER,CC_EXP_MONTH FROM BILLING_DETAILS WHERE BILLING_DETAILS_TYPE=’CC’
注:当类继承关系比较多时,存在性能问题
节 1.03 每个子类一个表 – JoinSubClass
将一个表示逻辑的大表拆分成多个子表,每个子表通过主键 / 外键的关系同父表进行关联,从而形成继承关系。每个子表的主键同时时父表的外键
< class name = "hibernate.hierarchical.BillingDetails" table = "BillingDetails" >
< joined-subclass name = "hibernate.hierarchical.CreditCard" table = "CREDIT_CARD" >
<!-- 通过 key 指定的字段将父表和子表关联。 CREDIT_CARD_ID 即使子表的主键同时也是父表的外键 -->
< key column = "CREDIT_CARD_ID" />
< property name = "number" column = "NUMBER" />
< property name = "expMonth" column = "EXP_MONTH" />
< property name = "expYear" column = "EXP_YEAR" />
</ joined-subclass >
< joined-subclass name = "hibernate.hierarchical.BankAccount" table = "BANK_ACCOUNT" >
< key column = "BANK_ACCOUNT_ID" />
<