Hibernate实战_笔记29(每个类层次结构一张表)
来源:互联网 发布:王侯将相焉有种乎出自 编辑:程序博客网 时间:2024/05/23 02:21
整个类层次结构可以被映射到单张表。这张表把所有类的所有属性的列都包括在层次结构中。由特定行表示的具体子类通过一个类型辨别标志列的值进行识别。
这个映射策略在性能和简单性方面都胜出一筹。它是表示多态的最佳方法——多态和非多态的查询都执行得很好——并且更易于手工实现。不用复杂的联结或者联合也有可能生成特殊的报表。有一个重大的问题:子类声明的属性的列必须声明为可为空。如果每个子类都定义几个可为空的属性,从数据库完整性的角度来说,没有NOT NULL约束可能会是一个严重的问题。另一个重要的问题是标准化。我们已经创建了非键列之间的依赖,违背了第三范式。跟往常一样,性能的反规范化可能会令人误解,因为它为了也能通过SQL执行计划的适当优化而也可能实现的即时获取,却牺牲了数据的长期稳定性、可维护性和数据完整性。
在Hibernate中,用<subclass>元素给每个类层次结构映射创建一张表:
<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文件,则默认为实体名称。
以下是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长期而言会变成一个重大的负担。你的数据库管理员根本不可能喜欢它。
1 0
- Hibernate实战_笔记29(每个类层次结构一张表)
- Hibernate实战_笔记27(每个带有隐式多态的具体类一张表)
- Hibernate实战_笔记28(每个带有联合的具体类一张表)
- Hibernate映射类继承之每个类层次结构一张表(父子类共用一张表,一个映射文件)
- Hibernate学习笔记:混合使用每个继承结构一张表 和 每个子类一张表
- Hibernate实战_30(每个子类一张表)
- Hibernate学习笔记:继承映射之每个类继承结构一张表
- hibernate继承结构中每个类一张表
- Hibernate学习笔记:每个具体的类一张表
- Hibernate学习笔记:每个具体的类一张表
- Hibernate学习笔记:继承映射之每个子类一张表
- 使用JPA的@SecondaryTable来实现hibernate的混合使用“每个类分层结构一张表”和“每个子类一张表”的功能
- 每个类一张表
- Hibernate系列之继承关系:每个类一张表
- Hibernate继承映射之每个类一张表
- Hibernate继承映射之每个具体类一张表
- hibernate继承映射策略之每个具体类一张表
- Hibernate教程03——类继承(每个类一张表)
- 基于OpenLayers的代理文件内容 GeoServerProxy?URL
- C++11 性能Range-based for loops
- ubuntu下ftp的设置及登录
- “微风”团队的人员结构
- java的23种设计模式
- Hibernate实战_笔记29(每个类层次结构一张表)
- Android开发有关设置跳转网络设置界面出错的分析
- ActiveMQ集群:网络连接模式(network connector)详解
- Call to undefined function getsqlvaluestring() with Dreamweaver PHP mysql
- ceph的部署及遇到的问题
- 难为自己
- Unity中Mecanim工作流
- Qt进行UrlEncode/UrlDecode(URL编码/解码)
- 进程和线程之间的区别和联系总结