Hibernate的3种继承映射策略

Hibernate的3种继承映射策略:

	注意:映射文件名为:父类名.hbm.xml

	1,父类和子类使用同一张表:采用 subclass 元素的继承映射

		1)因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为鉴定者列(discriminator)
		2)使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定鉴定者列的值
		注:所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中

		父类:Article
		子类:Topic、Reply
		
		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_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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值