Hibernate映射之“继承映射”-joined and union

在上一篇中,笔者向各位介绍了,Hibernate映射关系中的继承映射,其实说白了,就是将面向对象的思想,应用到表的设计当中去,本篇再介绍2个继承映射策略,读者可根据实际的需求而选择对应的继承策略

1.joined-subclass

简单介绍下这种继承映射的效果,父类的实例依然保存在父类表中,而子类实例中不属于父类属性的延展属性保存在子类表中,父类属性依旧保存在父类中,下面给出这类映射策略的xml配置。

<hibernate-mapping package="com.sooen.domain">
	<!-- 映射Person类 -->
	<class name="Person" table="person_inf">
		<!-- 映射标识属性 -->
		<id name="id" column="person_id">
			<!-- 使用native的主键生成器策略 -->
			<generator class="native"/>
		</id>
		<property name="name" type="java.lang.String" length="50">
			<column name="name">
				<comment>姓名</comment>
			</column>
		</property>
		
		<property name="age" type="java.lang.String" length="50">
			<column name="age">
				<comment>年龄</comment>
			</column>
		</property>
		
		<property name="sex" type="java.lang.String" length="50">
			<column name="sex">
				<comment>性别</comment>
			</column>
		</property>
		 
		<!-- 使用joined-subclass元素映射Person类的子类Employee -->
		<joined-subclass name="Employee" >
			<key>
				<column name="emp_id"></column>
			</key>
			<!-- 映射一个基本属性 -->
			<property name="position">
				<column name="position">
					<comment>职务</comment>
				</column>
			</property>
		 </joined-subclass>
	</class>
</hibernate-mapping>
下面是控制台输出的建表语句

create table Employee (
        emp_id varchar(255) not null,
        position varchar(255) comment '职务',
        primary key (emp_id)
    ) type=InnoDB

    create table person_inf (
        person_id varchar(255) not null auto_increment,
        name varchar(255) comment '姓名',
        age varchar(255) comment '年龄',
        sex varchar(255) comment '性别',
        primary key (person_id)
        foreign key (emp_id) 
        references person_inf (person_id)
    ) type=InnoDB
分析一下这种映射策略下的建表语句与之前的subclass有什么不一样,在配置中,没有使用discriminator辨别者,但是有了外键关联的性质,从数据存储的角度来说,这种表设计可以减少数据库的冗余程度,增加数据库存储的利用率,但是从查询的角度而言,有了外键关联的表,若是查询子类的实例,则要进行多表查询,会影响其性能。

2.union-subclass 

这种继承映射策略与上述的joined-subclass非常类似,唯一的不同是,父类实例存在父类表中,子类实例存在子类表中,子类表和父类表从数据库的角度而言,压根是看不出来有继承关系的,下面是这种映射机制的xml配置

<hibernate-mapping package="com.sooen.domain">
	<!-- 映射Person类 -->
	<class name="Person" table="person_inf">
		<!-- 映射标识属性 -->
		<id name="id" column="person_id">
		</id>
		<property name="name" type="java.lang.String" length="50">
			<column name="name">
				<comment>姓名</comment>
			</column>
		</property>
		
		<property name="age" type="java.lang.String" length="50">
			<column name="age">
				<comment>年龄</comment>
			</column>
		</property>
		
		<property name="sex" type="java.lang.String" length="50">
			<column name="sex">
				<comment>性别</comment>
			</column>
		</property>
		 
		<!-- 使用union-subclass元素映射Person类的子类Employee -->
		<union-subclass name="Employee" table="emp_inf">
			<!-- 映射一个基本属性 -->
			<property name="position">
				<column name="position">
					<comment>职务</comment>
				</column>
			</property>
		 </union-subclass>
	</class>
</hibernate-mapping>
    create table emp_inf (
        person_id varchar(255) not null,
        name varchar(255) comment '姓名',
        age varchar(255) comment '年龄',
        sex varchar(255) comment '性别',
        position varchar(255) comment '职务',
        primary key (person_id)
    ) type=InnoDB

    create table person_inf (
        person_id varchar(255) not null,
        name varchar(255) comment '姓名',
        age varchar(255) comment '年龄',
        sex varchar(255) comment '性别',
        primary key (person_id)
    ) type=InnoDB




通过这个配置,反观之前的joined-subclass配置和上一篇的subclass配置,可以明显的发现,更加简洁了,没有采用外键关联,也没有采用辨别者列,不同的是没用使用id生成策略,笔者在测试的时候,发现设置了id生成策略之后,会出现问题,后来多方查阅资料才发现,再这类配置下,id是要统一管理起来的,不能使用数据库的生成策略,可以算是这个策略的一个缺憾吧。但是,反观这个配置的表结构,表和表之间没有外键相关联,实际中的父类和子类都是存在对应的表中的,这种生成策略更加符合数据库底层表的设计。而查询的时候,数据库都对数据进行union操作。
现在Hibernate的三种继承映射机制就写完了,subclass策略,展现了是对查询性能的提高,joined-subclass则是对数据冗余度进行了优化,union-subclass则更加符合底层的设计,读者可以根据自己的需求来进行相对应的策略配置。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值