【Hibernate】继承映射
来源:互联网 发布:什么是可逆矩阵 编辑:程序博客网 时间:2024/05/14 06:39
【前言】
根据图建立对应的对象模型,也就是所说的实体类,本篇博客中实体类代码就不再展示了。
3. 配置及注释:
不知道大家是否还记得UML中的四种关系?自己回想了一下,还是没有忘记的,分别是继承、实现、依赖和关联。
怎么突然会想到这样一个问题?是因为在学习完Hibernate关联映射之后,紧接着又来了一个继承映射。关联和继承,都属于四种关系之一,所以,本篇博客就先提了个问题,下面就开始继承映射的学习。
【概述】
继承是面向对象语言的三大重要特性之一,它实现了代码的复用。而Hibernate对于此特性在对应的对象模型配置文件中也作出了各种配置,可将其与关系模型的关系分为三种情况:
1. 每棵类继承树一张表
2. 每个类一张表
3. 每个具体类一张表
下面我们就逐一看看,它们各自生成的关系模型有着哪些不同?以下通过动物类和猪类、鸟类三者间的关系为实例,利用不同继承映射的方法去建表。
三个类之间的关系如下所示:
【一、继承映射之每棵类继承树一张表】
1. 含义:此方法的意思是不管父类拥有多少个子类,都只会根据父类去生成一张表,而各个子类中有单独的字段,都添加到父类生成的那张表中。
2. 设计:从图上看,这张表至少包含的字段有:id,name,sex,weight和height。但因为子类不止一个,如果没有一个标识字段,那么就无法从数据表中看到记录是属于哪个子类的。所以,此张表的结构与数据应该如下:
t_animal:
IdNameSexWeightHeightType1小猪猪True200 P2小鸟鸟False 100B
3. 配置及注释:
<?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.bjpowernode.hibernate"> <!-- 新建表,名为t_animal。不采用延迟加载 --> <class name="Animal" table="t_animal" lazy="false"> <!-- 该表的主键字段id,生成策略为native --> <id name="id"> <generator class="native"/> </id> <!-- 在父类使用discrimination标签,用来指定标识字段的列名和类型 --> <discriminator column="type" type="string"/> <!-- 父类的name属性 --> <property name="name"/> <!-- 父类的sex属性 --> <property name="sex"/> <!-- 子类Pig,标识字段值为P --> <subclass name="Pig" discriminator-value="P"> <!-- 子类Pig的weight属性 --> <property name="weight"/> </subclass> <!-- 子类Bird,标识字段值为B --> <subclass name="Bird" discriminator-value="B"> <!-- 子类Bird的height属性 --> <property name="height"/> </subclass> </class></hibernate-mapping>4. 结果:
5. 小结:
此种方法的结果就是数据库中只有一张根据父类建立的表,而不同子类的子属性也全都写入到这张表中,增加一个区分字段即可。
6. 优缺点:
(1)表中引入的区分子类的字段,也就是包括了描述其他字段的字段。
(2)如果某个子类的某个属性不能为空,那么在数据库一级不能设置该字段not null(非空)
(3)维护起来方便,只需要修改一个表
(4)灵活性差,表中冗余字段会随着子类的增多而越来越多
【二、继承映射之每个类一张表】
1. 含义:此种方法的意思是每个类都建立一张单独的表。
2. 设计:从图上看,共包含三个类,则应该建立三张表:t_animal、t_pig和t_bird。三张表的结果和数据如下所示:
3. 配置即注释:<?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.bjpowernode.hibernate"><!-- 建立表t-animal --> <class name="Animal" table="t_animal"> <!-- 该表的主键字段id,生成策略为native --> <id name="id"> <generator class="native"/> </id> <!-- t_animal的属性字段name和sex --> <property name="name"/> <property name="sex"/> <!-- joined-subclass生成策略,新建表t_pig --> <joined-subclass name="Pig" table="t_pig"> <!-- 指定了pig子类和animal父类之间是通过pid字段关联 --> <key column="pid"/> <!-- pig子类的子属性,weight --> <property name="weight"/> </joined-subclass> <!-- joined-subclass生成策略,新建表t_bird --> <joined-subclass name="Bird" table="t_bird"> <!-- 指定了bird子类和animal父类之间是通过bid字段关联 --> <key column="bid"/> <!-- bird子类的子属性,height --> <property name="height"/> </joined-subclass> </class></hibernate-mapping>4. 结果:
5. 小结:
此种方法的结果是数据库中每个类都对应生成一张表,父类拥有自己的属性字段,子类加上与父类关联的主键字段和自己的子属性。
6. 优缺点:
(1)这种设计方式完全符合关系模型的设计原则,且不存在冗余
(2)维护起来比较方便,对每个类的修改只需要修改其所对应的表,灵活性很好,完全是参照对象继承的方式进行配置
(3)对于父类的查询需要使用左外链接,对于子类查询需要使用内链接
(4)对于子类的持久话至少要处理两个表
【三、继承映射之每个具体类一张表】
1. 含义:此种方法的意思是每个子类都建立一张单独的表,而父类不生成对应的表。
2. 设计:从图上看,共包含两个具体类,则应该建立两张表:t_pig和t_bird。两张表的结果和数据如下所示:
3. 配置即注释:<?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.bjpowernode.hibernate"><!-- 定义该表的abstract属性为true,则不会生成具体的表 --> <class name="Animal" table="t_animal" abstract="true"> <id name="id"> <!-- 让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。 --> <generator class="assigned"/> </id> <property name="name"/> <property name="sex"/> <!-- union-subclass生成策略,t_pig表的信息是完整的,也就是包含id,name,sex和weight四个字段 --> <union-subclass name="Pig" table="t_pig"> <!-- 子属性字段weight --> <property name="weight"/> </union-subclass> <!-- union-subclass生成策略,t_bird表的信息是完整的,也就是包含id,name,sex和height四个字段 --> <union-subclass name="Bird" table="t_bird"> <!-- 子属性字段height --> <property name="height"/> </union-subclass> </class></hibernate-mapping>4. 结果:
5. 小结:
此种方法的结果是数据库中每个子类都对应生成一张表,每个子类的属性是各自的子属性加上父类的共同属性。
6. 优缺点:
(1) 这种设计方式符合关系模型的设计原则,但有表中存在重复字段的问题。
(2) 如果需要对基类进行修改,则需要对基类以及该类的子类所对应的所有表都进行修改
(3) 对于子类的查询只需要访问单独的表,对父类查询需要检索所有的表,对于单个对象持久话操作只需要处理一个表
【总结】
对于这三种继承映射方法,目前还没有在项目中遇到过,所以三者之间如何选择?通常选择什么?都没有概念。不过总体思想应该仍旧是:没有最好,选择合适的就好。也期待在项目中见到对它们的应用。
1 0
- Hibernate高级映射 --- 继承映射
- Hibernate高级映射--继承映射
- Hibernate高级映射-继承映射
- Hibernate映射解析---继承映射
- Hibernate映射解析---继承映射
- Hibernate映射解析---继承映射
- Hibernate 简化继承映射
- Hibernate 简化继承映射
- Hibernate 简化继承映射
- Hibernate 简化继承映射
- Hibernate 简化继承映射
- Hibernate 简化继承映射
- Hibernate的继承映射
- hibernate继承映射2
- Hibernate 继承关系映射
- hibernate继承映射
- hibernate总结---继承映射
- Hibernate继承映射(1)
- 【codeforces 721B】B. Passwords【输入密码按长度非递减顺序输入,每输一次耗时1秒,输错k次等待5秒,最后一行为正确密码,问消耗的最少和最多时间】
- 微机原理--第二章(9)描述符和页表项
- Unity3D自学笔记——GUI组件的应用
- uva困难的串
- 颜色值合辑
- 【Hibernate】继承映射
- TCP协议与UDP协议的区别
- 18、构建Maven的分模块的项目
- Wild pointer, NULL pointer, generic pointer and dangling pointer
- POJ 1228 Grandpa's Estate (凸包唯一性判定 推荐)
- python基础系列(三)之高级数据结构
- Android开发中使用WebView控件显示找不到网页的解决方法
- IT职场
- CodeForces 374(div2)