1)每个带有隐式多态的具体类一张表——使用非显式的继承映射和默认的运行时多态行为。
2)每个具体类一张——完全放弃来自SQL模式的多态和继承关系。
3)每个类层次结构一张表——通过的反规范化SQL模式启用多态,并利用保存类型信息的一个类型辨别标志列。
4)每个子类一张表——把is a(继承)关系表示为has a(外键)关系。
每个带有隐式多态的具体类一张表
这种方法的主要问题在于,它不太支持多态关联。如果子类全部被映射到不同的表,对它们基类(本例中为抽象的BillingDetails)的多态关联就无法被表示为一个简单的外键关系。这在我们的领域模型中会有问题,因为BillingDetails与User关联;两张子类表都需要一个对USERS表的外键引用。或者,如果User与BillingDetails有个多地一的关系,USERS表就需要单个的外键列,它必须同时引用两个具体的子类表。这用一般的外键约束是不可能的。
多态查询(它返回与被查询类的接口相匹配的所有类的对象)也有问题。
这种映射策略进一步的概念问题在于,几张不同表的几个不同的列具有完全相同的主义。这使得模式变得更为复杂。例如,对一个基类属性的改变导致了多个列的变化。它也使得把应用到所有子类的数据库完整性约束实现起来变得更加困难。
Java Persistence接口也不支持完全的多态查询;只有被映射的实体(@Entity)可以正式成为Java Persistence查询的一部分(注意Hibernate查询接口是多态的,即使你用注解映射)。
JPA注解实现每个带有隐式多态的具体类一张表
@MappedSuperclass public abstract class BillingDetails1 { @Column(name = "OWNER", nullable = false) private String owner; }
现在映射具体的子类:
@Entity @AttributeOverride( name="owner", column=@Column( name = "CC_OWNER", nullable = false ) ) public class CreditCard1 extends BillingDetails1 { @Id @GeneratedValue @Column(name = "CREDIT_CARD_ID") private Integer id; @Column(name = "CC_NUMBER", nullable = false) private String number; @Column(name = "EXP_MONTH", nullable = false) private String expMonth; @Column(name = "EXP_YEAR", nullable = false) private String expYear; }可以用@AttributeOverride注解在一个子类中覆盖来自超类的列映射。在CREDIT_CARD表中重新命名OWNER列为CC_OWNER。数据库标识符也可以在超类中声明,给所有的子类使用一个共用的列名和生成器策略。
在JPA XML描述符中重复相同的映射:
<mapped-superclass class="cn.jbit.hibernate.entity1.BillingDetails1" access="FIELD"> <attributes> <basic name="owner"> <column name="OWNER" nullable="false"/> </basic> </attributes> </mapped-superclass> <entity class="cn.jbit.hibernate.entity1.CreditCard1" access="FIELD"> <attribute-override name="owner"> <column name="CC_OWNER" nullable="false"/> </attribute-override> <attributes> <id name="id"> <column name="CREDIT_CARD_ID" nullable="false"/> <generated-value strategy="AUTO"/> </id> <basic name="number"> <column name="CC_NUMBER" nullable="false"/> </basic> <basic name="expMonth"> <column name="EXP_MONTH" nullable="false"/> </basic> <basic name="expYear"> <column name="EXP_YEAR" nullable="false"/> </basic> </attributes> </entity>说明:(组件是值类型)可以把子类映射为组件,通过所超类(或者接口)的所有属性都包括在组件映射中。有了注解,可以在正映射的可嵌入组件的超类上使用@MappedSuperclass注解,就像对实体使用时一样。注意该特性仅在Hibernate Annotations中可用,不是标准的或者可移植的。
在SQL UNION操作的帮助下,可以解决多态查询和关联的大部分问题,这些问题是这个映射策略所带来的。