Hibernate映射类继承之每个带有隐式多态的具体类一张表(每个子类各一张表,有各自的映射文件)

来源:互联网 发布:广西玉林软件 编辑:程序博客网 时间:2024/04/29 14:04
Hibernate映射类继承之每个带有隐式多态的具体类一张表(每个子类各一张表)
我们可以准确地给每个子类使用一张表。子类的所有属性,包括被继承的属性,都可以被映射到这张表的列。如图:
                        CreditCard子类   ----->  CreditCard.hbm.xml   ----->  CREDIT_CARD表
BillingDetails父类---->
                        BankAccount子类  ----->  BankAccount.hbm.xml  ----->  BANK_ACCOUNT表
                        
在Hibernate中你不必做任何特别的事来启用多态行为。对CreditCard和BankAccount的映射很简单,各自都在自己的实体<class>元素中,就像我们已经没有基类的类所做的那样。Hibernate仍然知道这个基类或者接口,因为它在启动时扫描持久化类。这种方法的主要问题在于,它不太支持多态关联。在数据库中,关联通常被表示为外键关系。如果子类全部被映射到不同的表,对它们基类(本例BillingDetails)的多态关联就无法被表示为一个简单的外键关系。这在我们的领域模型中会有问题,如果BillingDetails与一个存在的user关联,两张子类表都需要一个对User表的外键引用。或者,如果User与BillingDetails有个多对一的关系,USER表就需要单个的外键列,它必须同时引用两个具体的子类表。这用一般的外键约束是不可能的。
多态查询(它返回与被查询类的接口相匹配的所有类的对象)也有问题。针对基类的查询必须作为几个SQL SELECT执行,每个具体的子类一个。对于针对BillingDetails类的查询,hibernate使用下列SQL:
select CREDIT_CARD_ID,OWNER,NUMBER,EXP_MONTH,EXP_YEAR... from CREDIT_CARD;
select BANK_ACCOUNT_ID,OWNER,ACCOUNT,BANKNAME,... from BANK_ACCOUNT;
注意每个具体的子类都需要一个单独的查询。
这种映射策略进一步的概念问题在于,几张不同表的几个不同的列具有完全相同的语义。这使得模式演变更为复杂。例如,对一个基类属性的改变导致了多个列的变化。它也使得把应用到所有子类的数据库完整性约束实现起来变得更加困难。
我们推荐这种方法(仅仅)用于类层次结构的最顶层,那里通常不需要多态,且未来也不太可能修改基类。

pom.xml:
 
hibernate.cfg.xml:
 
父类,BillingDetails.java:
 
子类,BankAccount.java:
 
子类的映射,BankAccount.hbm.xml:
 
子类,CreditCard.java:
 
子类映射,CreditCard.hbm.xml:
 
util/HibernateUtil.java:
 
util/Manager.java:
 
输出sql与日志:
 
注意,这里有两张表:CREDIT_CARD , BANK_ACCOUNT.

CREDIT_CARD表:
CREDIT_CARD_ID
OWNER
NUMBER
EXP_MONTH
EXP_YEAR
BANK_ACCOUNT表:
BANK_ACCOUNT_ID
OWNER
ACCOUNT
BANKNAME
SWIFT