Hibernate的3种继承映射策略

来源:互联网 发布:淘宝卖家升级信用升级 编辑:程序博客网 时间:2024/04/25 08:30
Hibernate的3种继承映射策略:注意:映射文件名为:父类名.hbm.xml1,父类和子类使用同一张表:采用 subclass 元素的继承映射1)因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为鉴定者列(discriminator)2)使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定鉴定者列的值注:所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中父类:Article子类:Topic、ReplyArticle.hbm.xml文件:<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.jxn.hbm_extends"><!-- discriminator-value属性:指定鉴定者列的值;如果不写,默认为类的全限定名。--><class name="Article" table="article" discriminator-value="Aticle"><id name="id"><generator class="native"/></id><!-- 用于鉴定是什么类型的一个列,必须写在id标签的下面 --><discriminator type="string" column="class_"></discriminator><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子类:Topic --><subclass name="Topic" discriminator-value="Topic"><property name="type"></property></subclass><!-- 子类:Reply --><subclass name="Reply" discriminator-value="Reply"><property name="floor"></property></subclass></class></hibernate-mapping>2,每个类(包括父类)对应一个表:采用 joined-subclass 元素的继承映射1)子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。2)通过关系数据模型中的外键来描述表之间的继承关系,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。如果继承树的深度很深,可能查询一个子类实例时,需要跨越多个表,因为子类的数据保存在多个父类中注:子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中Article.hbm.xml文件:<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.jxn.hbm_extends2"><!-- 采用每个类一张表的方式,父类也对应表。 --><class name="Article" table="article2"><id name="id"><generator class="native"/></id><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子类:Topic --><joined-subclass name="Topic" table="topic2"><key column="id"></key><property name="type"></property></joined-subclass><!-- 子类:Reply --><joined-subclass name="Reply" table="reply2"><key column="id"></key><property name="floor"></property></joined-subclass></class></hibernate-mapping>3,每个子类(不包括父类)对应一张表:采用 union-subclass 元素的继承映射1)子类实例的数据仅保存在子类表中, 而在父类表中没有任何记录2)子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段和子类增加属性的总和3)既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键注:使用 union-subclass 映射策略是不可使用 identity 的主键生成策略, 因为在整个继承结构中,主键值是不能重复的,受此影响, 也不该使用 native 主键生成策略, 因为 native 会根据数据库来选择使用 identity 或 sequence.Article.hbm.xml文件:<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.jxn.hbm_extends3"><!-- 采用每个子类对应一张表的方式,父类不对应表。abstract默认为false,设为true表示本类不对应表(类可以不是abstract的),这时就会忽略table属性。--><class name="Article" abstract="false" table="article3"><id name="id"><!-- 主键生成策略不能是identity、sequence、native等自动增长的类型,因为在整个继承结构中,主键值是不能重复的。--><generator class="hilo"><param name="table">hi_value</param><param name="column">next_value</param><param name="max_lo">100</param></generator></id><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子类:Topic --><union-subclass name="Topic" table="topic3"><property name="type"></property></union-subclass><!-- 子类:Reply --><union-subclass name="Reply" table="reply3"><property name="floor"></property></union-subclass></class></hibernate-mapping>

0 0