整个类层次结构可以被映射到单张表。这张表把所有类的所有属性的列都包括在层次结构中。由特定行表示的具体子类通过一个类型辨别标志列的值进行识别。
这个映射策略在性能和简单性方面都胜出一筹。它是表示多态的最佳方法——多态和非多态的查询都执行得很好——并且更易于手工实现。不用复杂的联结或者联合也有可能生成特殊的报表。<hibernate-mapping package="cn.jbit.hibernate.entity3"> <class name="BillingDetails4" table="BILLING_DETAILS"> <id name="id" column="BILLING_DETAILS_ID" type="integer"> <generator class="native"/> </id> <discriminator column="BILLING_DETAILS_TYPE" type="string" /> <property name="owner"> <column name="OWNER" not-null="true"/> </property> <subclass name="CreditCard4" discriminator-value="CC"> <property name="number" column="CC_NUMBER" length="20" not-null="true"/> <property name="expMonth" column="EXP_MONTH" length="20" not-null="true"/> <property name="expYear" column="EXP_YEAR" length="20" not-null="true"/> </subclass> </class> </hibernate-mapping>JPA中也有这个映射策略,即SINGLE_TABLE:
@Entity @Table(name = "BILLING_DETAILS2") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name = "BILLING_DETAILS_TYPE", discriminatorType = DiscriminatorType.STRING ) public abstract class BillingDetails5 { @Id @GeneratedValue @Column(name = "BILLING_DETAILS_ID", nullable = false) private Integer id; @Column(name = "OWNER", nullable = false) private String owner; }如果没有在超类中指定辨别标志列,它的名称就默认为DTYPE,且它的类型默认为字符串。继承层次结构中所有具体的类都可以有辨别标志值。
@Entity @Table(name = "CREDIT_CARD2") @DiscriminatorValue("CC") public class CreditCard5 extends BillingDetails5 { @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; }没有显式的辨别标志值时,如果使用Hibernate XML文件,Hibernate就默认认为完全限定的类名;如果使用注解或者JPA XML文件,则默认为实体名称。
<entity class="cn.jbit.hibernate.entity3.BillingDetails3" access="FIELD"> <inheritance strategy="SINGLE_TABLE"/> <discriminator-column name="BILLING_DETAILS_TYPE" discriminator-type="STRING"/> <attributes> <id name="id"> <column name="BILLING_DETAILS_ID" nullable="false"/> <generated-value strategy="AUTO"/> </id> <basic name="owner"> <column name="OWNER" nullable="false"/> </basic> </attributes> </entity> <entity class="cn.jbit.hibernate.entity3.CreditCard3" access="FIELD"> <discriminator-value>CC</discriminator-value> <attributes> <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>有时候,尤其在遗留的Schema中,你无权在实体表中包括一个额外的辨别标志列。此时,可以应用一个formula来计算每一行的辨别标志值。
<discriminator formula="case when CC_NUMBER is not null then ‘CC‘ else ‘BA‘ end" type="string" />用于辨别的公式不是JPA规范的一部分,但是可以应用Hibernate注解:
@org.hibernate.annotations.DiscriminatorFormula( "case when CC_NUMBER is not null then ‘CC‘ else ‘BA‘ end" )每个类层次结构一张表的策略的缺点对于你的设计来说可能太严重了——毕竟,反规范化的Schema长期而言会变成一个重大的负担。你的数据库管理员根本不可能喜欢它。
Hibernate实战_笔记29(每个类层次结构一张表),布布扣,bubuko.com
原文:http://blog.csdn.net/com185272358/article/details/22332595