hibernate继承关系映射

在问题域中实体之间的继承关系在数据库中有多种体现方式。在hibernate中,要实现面向对象的对实体进行持久化操作,那么就需要对实体类进行继承关系映射。


根据数据表的不同形态,映射方案有三种

实体继承关系模型:




1.Tpc每个具体类一张表


mysql> show tables;

+-------------------+

| Tables_in_db_test |

+-------------------+

| tb_student          |

| tb_worker           |

+-------------------+

2 rows in set (0.00 sec)

表结构:

mysql> desc tb_student;

+--------+--------------+------+-----+---------+-------+

| Field  | Type           | Null | Key | Default | Extra |

+--------+--------------+------+-----+---------+-------+

| id     | int(11)        | NO    | PRI | NULL     |       |

| name   | varchar(255)  | YES  |      | NULL      |       |

| sex    | varchar(255)  | YES  |      | NULL      |       |

| age    | int(11)        | YES  |      | NULL      |       |

| sno    | varchar(255)  | YES  |      | NULL    |       |

| school | varchar(255) | YES  |      | NULL    |       |

+--------+--------------+------+-----+---------+-------+

mysql> desc tb_worker;

+--------+--------------+------+-----+---------+-------+

| Field  | Type         | Null | Key | Default | Extra |

+--------+--------------+------+-----+---------+-------+

| id     | int(11)      | NO   | PRI | NULL    |       |

| name   | varchar(255) | YES  |     | NULL    |       |

| sex    | varchar(255) | YES  |     | NULL    |       |

| age    | int(11)      | YES  |     | NULL    |       |

| no     | varchar(255) | YES  |     | NULL    |       |

| salary | double       | YES  |     | NULL    |       |

+--------+--------------+------+-----+---------+-------+


Person.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="entities">
	<!-- table per concrete (a. 具体的,实际的) -->
	<!-- 每一个具体类一张表 -->
	<!-- 虚拟选项为'true' -->
	<class name="Person" table="tb_person" abstract="true">
	<id column="id" name="id" type="java.lang.Integer">
		<!-- 主键的生成策略为'分配' -->
		<generator class="assigned"></generator>
	</id>
	<property column="name" name="name" type="string"></property>
	<property column="sex" name="sex" type="string"></property>
	<property column="age" name="age" type="java.lang.Integer"></property>
	
	<!--student具体类-->
	<union-subclass name="Student" table="tb_student">
		<property column="sno" name="sno" type="string"></property>		
		<property column="school" name="school" type="string"></property>
	</union-subclass>
	
	<!--worker具体类-->
	<union-subclass name="Worker" table="tb_worker">
		<property column="no" name="no" type="string"></property>
		<property column="salary" name="salary" type="java.lang.Double"></property>
	</union-subclass>
	
	</class>
</hibernate-mapping>



1.tph每个继承树一张表


mysql> show tables;

+-------------------+

| Tables_in_db_test |

+-------------------+

| tb_person         |

+-------------------+

mysql> desc tb_person;

+---------+--------------+------+-----+---------+-------+

| Field   | Type         | Null | Key | Default | Extra |

+---------+--------------+------+-----+---------+-------+

| id      | int(11)      | NO   | PRI | NULL    |       |

| discram | varchar(255) | NO   |     | NULL    |       |

| name    | varchar(255) | YES  |     | NULL    |       |

| age     | int(11)      | YES  |     | NULL    |       |

| sex     | varchar(255) | YES  |     | NULL    |       |

| school  | varchar(255) | YES  |     | NULL    |       |

| sno     | varchar(255) | YES  |     | NULL    |       |

| no      | varchar(255) | YES  |     | NULL    |       |

| salary  | double       | YES  |     | NULL    |       |

+---------+--------------+------+-----+---------+-------+

Person.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="entities">
	<!-- tph table per hierarchy 一个继承树一张表 -->
	<!-- 父类 -->
	<class name="Person" table="tb_person">
		<id column="id" name="id" type="java.lang.Integer">
			<!-- 主键生成策略为 '分配'  -->
			<generator class="assigned"></generator>
		</id>
		<!-- 鉴定列,区分列 discriminator 鉴-->
		<discriminator column="discram" type="string"></discriminator>
		<property column="name" name="name" type="string"></property>
		<property column="age" name="age" type="java.lang.Integer"></property>
		<property column="sex" name="sex" type="string"></property>
	
	<!-- 子类,其鉴定列值为'stu'-->
	<subclass name="Student" discriminator-value="stu">
		<property column="school" name="school" type="string"></property>
		<property column="sno" name="sno" type="string"></property>
	</subclass>
		
	<!-- 子类,其鉴定列值为'worker'-->
	<subclass name="Worker" discriminator-value="worker">
		<property column="no" name="no" type="string"></property>
		<property column="salary" name="salary" type="java.lang.Double"></property>
	</subclass>
	
	</class>
</hibernate-mapping>


1.tps每个子类一张表

mysql> show tables;

+-------------------+

| Tables_in_db_test |

+-------------------+

| tb_person         |

| tb_student        |

| tb_worker         |

+-------------------+

mysql> desc tb_person;

+-------+--------------+------+-----+---------+-------+

| Field | Type         | Null | Key | Default | Extra |

+-------+--------------+------+-----+---------+-------+

| id    | int(11)      | NO   | PRI | NULL    |       |

| name  | varchar(255) | YES  |     | NULL    |       |

| sex   | varchar(255) | YES  |     | NULL    |       |

| age   | int(11)      | YES  |     | NULL    |       |

+-------+--------------+------+-----+---------+-------+

mysql> desc tb_student;

+-----------+--------------+------+-----+---------+-------+

| Field     | Type         | Null | Key | Default | Extra |

+-----------+--------------+------+-----+---------+-------+

| studentid | int(11)      | NO   | PRI | NULL    |       |

| sno       | varchar(255) | YES  |     | NULL    |       |

| school    | varchar(255) | YES  |     | NULL    |       |

+-----------+--------------+------+-----+---------+-------+

mysql> desc tb_worker;

+----------+--------------+------+-----+---------+-------+

| Field    | Type         | Null | Key | Default | Extra |

+----------+--------------+------+-----+---------+-------+

| workerid | int(11)      | NO   | PRI | NULL    |       |

| no       | varchar(255) | YES  |     | NULL    |       |

| salary   | varchar(255) | YES  |     | NULL    |       |

+----------+--------------+------+-----+---------+-------+


Person.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="entities">
	<!-- Person表 -->
	<class name="Person" table="tb_person">
		<id name="id">
			<!-- 父类的主键生成策略为‘分配’ -->
			<generator class="assigned"></generator>
		</id>
		<property name="name" type="string"></property>
		<property name="sex" type="string"></property>
		<property name="age" type="java.lang.Integer"></property>
		
		<!-- student表 -->
		<joined-subclass name="Student" table="tb_student">
			<key column="studentid"></key>
			<property column="sno" name="sno" type="string" ></property>
			<property column="school" name="school" type="string" ></property>	
		</joined-subclass>
		
		<!-- worker表 -->
		<joined-subclass name="Worker" table="tb_worker">
			<key column="workerid"></key>
			<property column="no" name="no" type="string" ></property>
			<property column="salary" name="salary" type="string" ></property>
		</joined-subclass>
	</class>
</hibernate-mapping>



三种映射方式的优缺点



方式一:整个的继承体系就用一张表(table per 

hierarchy)


建立关系模型原则:描述一个继承关系只用一张表

优缺点:首先表中引入的区分子类的字段,也就是包括了描述其他字段的字段。其次,如果某个子类的某个属性不能为空,那么在数据库一级不能设置该字段not null(非空),维护起来方便,只需要修改一个表,灵活性差,表中冗余字段会随着子类的增多而越来越多,在任何情况下,都只需处理一个表,对于单个对象的持久话操作只需要处理一个表


方式二:每个子类一张表,存放子类所特有的属性(table per subclass)


建立关系模型原则每个子类使用一张表,但这些子类所对应的表都关联到基类所对应的表中

优缺点:这种设计方式完全符合关系模型的设计原则,且不存在冗余,维护起来比较方便,对每个类的修改只需要修改其所对应的表,灵活性很好,完全是参照对象继承的方式进行配置,对于父类的查询需要使用左外链接,对于子类查询需要使用内链接,对于子类的持久话至少要处理两个表


方式三:每个具体类一张表(union-subclass) ,保存是子类完整信息(table per 

concrete )


建立关系模型原则每个具体类对应一张表,有多少具体类就需要建立多少个独立的表

优缺点:这种设计方式符合关系模型的设计原则,但有表中存在重复字段的问题。如果需要对基类进行修改,则需要对基类以及该类的子类所对应的所有表都进行修改,映射的灵活性很大,子类可以包括基类属性在内的每一个属性进行单独配置,对于子类的查询只需要访问单独的表,对父类查询怎需要检索所有的表,对于单个对象持久话操作只需要处理一个表


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值