Hibernate(七):继承映射
来源:互联网 发布:有个微信精准定位软件 编辑:程序博客网 时间:2024/05/22 17:38
继承是面向对象的特性,在Hibernate 中是以面向对象的思想进行持久化操作,所以在Hibernate中数据表所映射的实体对象也是可以存在继承关系的。主要有三种继承关系:
1.类继承树映射成一张表(subclass)
将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承和多态。
(1)使用subclass的继承映射可以实现继关系中父类和子类使用一张表。
(2)因为父类和子类的实例都保存在一张表中,需要在这个表中增加一列,使用该类来区分每行记录到底是哪个类的实例,这个列被称为辨别者列(discriminator)
- 在这种映射策略下,使用subclass来映射子类。使用class或subclass的discriminator-value属性指定辨别者列的值
(3)所有的子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列中并没有值,这将引起数据库完整性冲突,导致数据添加失败。
实例:学生对象(Student)和 职员对象(Staff)共同继承了人的实体对象(Persont)。将这三个类映射到一张表中,为了辨明两个子类,需要在表中添加一个字段(辨别者列)type ,用来区分存储不同实体对象信息
代码:
Person.java
public class Person {private Integer id;// 唯一性标识private String name;// 姓名private String sex;// 性别private Integer age;// 年龄public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}Student.java
public class Student extends Person {private String school;//所在学校public String getSchool() {return school;}public void setSchool(String school) {this.school = school;}}Staff.java
public class Staffer extends Person {private String company;//所在的公司名称public String getCompany() {return company;}public void setCompany(String company) {this.company = company;}}
映射文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 继承树的映射配置 --> <hibernate-mapping package="com.mr.person"> <class name="Person" table="tab_person"> <id name="id"><generator class="native"/></id><!-- 声明一个鉴别器 --><discriminator column="type" type="string"/> <!-- 映射自有属性 --><property name="name" not-null="true"/><property name="age" type="int"/> <property name="sex" type="string"/> <!-- 声明子类Student --><subclass name="Student" discriminator-value="学生"><property name="school"/></subclass> <!-- 声明子类Staffer --><subclass name="Staffer" discriminator-value="职员"><property name="company"/></subclass> </class> </hibernate-mapping>
向表中插入数据,结果如下(两个子类信息在一张表中):
(1) 采用 joined-subclass 元素的继承映射可以实现每个子类一张表
- 采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。
- 在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键。
实例:将继承Person的两个子类映射到一张表中
代码:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 继承树的映射配置 --> <hibernate-mapping package="com.mr.person"> <class name="Person" table="tab_person1"> <id name="id"><generator class="native"/></id> <!-- 映射自有属性 --><property name="name" not-null="true"/><property name="age" type="int"/> <property name="sex" type="string"/> <!-- 映射子类Student --><joined-subclass name="Student" table="tab_student"><key column="id"/><property name="school"/></joined-subclass><!-- 映射子类Staffer --><joined-subclass name="Staffer" table="tab_staffer"><key column="id" /><property name="company"/></joined-subclass> </class> </hibernate-mapping>
插入数据,结果如下:
3.每个具体类映射成一张表(union-class)
将域模型中的每个类映射到一张表中,通过关系数据模型中的外键来描述表之间的继承关系。相当于按照域模型的结构来建立数据库中的表,并通过外键来建立表之间的继承关系。
(1)采用 union-subclass 元素可以实现将每一个实体对象映射到一个独立的表中。
- 子类增加的属性可以有非空约束 --- 即父类实例的数据保存在父表中,而子类实例的数据保存在子类表中。
- 子类实例的数据仅保存在子类表中, 而在父类表中没有任何记录
- 在这种映射策略下,子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段、加子类增加属性的总和
- 在这种映射策略下,既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键.
- 使用 union-subclass 映射策略是不可使用 identity 的主键生成策略, 因为同一类继承层次中所有实体类都需要使用同一个主键种子, 即多个持久化实体对应的记录的主键应该是连续的. 受此影响, 也不该使用 native 主键生成策略, 因为 native 会根据数据库来选择使用 identity 或 sequence.
代码:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 继承树的映射配置 --> <hibernate-mapping package="com.mr.person"> <class name="Person" abstract="true"> <id name="id"><!-- 主键生成策略为手动分配 --><generator class="assigned"/></id> <!-- 映射自有属性 --><property name="name" not-null="true"/><property name="age" type="int"/> <property name="sex" type="string"/> <!-- 映射子类Student --><union-subclass name="Student" table="tab_student2"><property name="school"/></union-subclass><!-- 映射子类Staffer --><union-subclass name="Staffer" table="tab_staffer2"><property name="company"/></union-subclass> </class> </hibernate-mapping>结果如下:
4.三种继承映射方式的比较
- Hibernate(七):继承映射
- hibernate 七, 继承映射
- Hibernate(七)——继承映射
- Hibernate(七)——继承映射
- Hibernate学习笔记(七)----集合映射、继承映射、作业
- 一口一口吃掉Hibernate(七)——继承映射
- hibernate详解(七)---映射继承关系
- 【Hibernate】(九)继承映射
- Hibernate映射详解(六)--继承映射
- Hibernate 简单使用(七)继承映射的几种方式
- 精通Hibernate之映射继承关系七(图)
- Hibernate(六)Hibernate继承关系映射
- 【Hibernate框架开发之七】Hibernate使用Annotation中各种关系映射的CRUD(增删改查)&&集合映射&&继承映射
- 【Hibernate框架开发之七】Hibernate使用Annotation中各种关系映射的CRUD(增删改查)&&集合映射&&继承映射
- Hibernate旅程(六)Hibernate映射--继承映射
- hibernate(七)-----关系映射(一)
- Hibernate高级映射 --- 继承映射
- Hibernate高级映射--继承映射
- Stream
- PHP开源技术大全(四)
- input值控制按钮样式
- spring boot + dubbo整合注意事项
- LWIP UDP socket编程 可以指定本地端口号及发送长度不能太长问题分析
- Hibernate(七):继承映射
- springboot,mybatics框架搭建基于idea
- Super Jumping! Jumping! Jumping! dp
- Spring框架笔记 _01
- leetcode--Largest Rectangle in Histogram
- Android 冷启动实现APP秒开
- 设置VS2017背景图片
- Spark学习-SparkSQL--04-SparkSQL CLI 单节点运行与yarn集群运行
- 广度优先搜索--推箱子