初识Hibernate之关联映射(二)
上篇我们介绍了关联映射的几种形式,有单向多对一,单向一对多,还有双向一对多。本篇接着介绍有关关联映射的其他几种映射方式,主要有以下几种:
- 基于外键的单向一对一关联映射
- 基于主键的单向一对一关联映射
- 单向多对多关联映射
一、基于外键的单向一对一关联映射
具有一对一关联的表结构也是很常见的,比如:一个人对应于一张身份证。于是我们的person表会有一个外键关联到 idcard表的主键,只要这个外键列唯一即可保证person到idcard表的关系由多对一变为一对一,也就是说单向的一对一关联映射其实上也就是外键列唯一的多对一的关联映射。例如:
public class Person {
private int id;
private String name;
private IdCard idcard;
//省略get,set方法
}
public class IdCard {
private int id;
private String code;
//省略get,set方法
}
<class name="Person" table="person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idcard" column="idcard_id" unique="true"/>
</class>
<class name="IdCard" table="idcard">
<id name="id">
<generator class="native"/>
</id>
<property name="code"/>
</class>
我们可以看到,几乎所有的代码和多对一关联映射都是差不多的,只不过在 many-to-one 元素中指定 unique="true",原来可以有多个具有相同外键值的记录映射到一的一端,现在指定外键值唯一之后,产生了唯一的一对一的关联映射。下面看看我们的测试代码:
//main 方法
Person p1 = new Person();
p1.setName("single");
IdCard idCard = new IdCard();
idCard.setCode("2345");
p1.setIdcard(idCard);
session.save(p1);
session.save(idCard);
我们分别创建两端的一个实例对象,然后由person端维护这种关联关系并将数据插入到数据库。看一眼结果:
这就是基于外键的单向一对一关联映射,与多对一的映射的唯一区别就在于,通过指定外键列唯一来让多的一端唯一,从而形成这种一对一的映射关系。
二、基于主键的单向一对一关联映射
所谓基于主键的映射就是指,其中的一张表的主键值依赖于另一张表的主键值。还是我们的人和身份证模型:
像这种IDCard表完全可以作为属性字段追加到person表的后面的情况(主键重复可覆盖),我们叫这种关联映射为基于主键的一对一关联映射。看看配置文件:
/*person实体类的映射文件的配置*/
<class name="Person" table="person">
<id name="id" column="pId">
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="idCard" constrained="true"/>
</class>
/*IDCard实体类的映射文件的配置*/
<class name="IdCard" table="idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="code"/>
</class>
可以看到,主要的变化还是在于实体类person。首先我们指定他的主键不再自增,而是由外键约束到其他表,对应的其他表的类型则是自己实体类的idCard属性对应的表。one-to-one标签则配置了person类中的IdCard属性,便于我们在取数据的时候Hibernate填充数据到该属性中。下面我们添加数据到数据库中,通过查看输出的Sql语句了解Hibernate是如何为我们创建关联的。
Person person = new Person();
person.setName("single");
IdCard idCard = new IdCard();
idCard.setCode("23456789");
person.setIdCard(idCard);
session.save(idCard);
session.save(person);
显然,我们对于idcard表的主键指定了native自增,而对于person表的主键并没有指定自增,person表的主键依赖于idcard的主键。我们并不用指定person表的主键值,因为person会根据和自己关联的idcard表的主键来为自己的主键赋值。
三、单向多对多关联映射
多对多的表关联类型也是非常常见的,例如:
很常见的一个例子,一个学生可以有多个老师,同时一个老师也可以有多个学生,那么这就是很明显的多对多的关联映射。针对这种情况,一般来说数据库的表可以设计如下:
但是这种的表结构设计将会直接导致student表大量冗余,虽然解决了这种多对多的表级关联,但是存在大量冗余。Hibernate中处理这种多对多的关联关系是通过引入另一张表来实现对两个表主键的关联进而关联了两张表。
Student表和teacher表之间的多对多关联完全由connect表进行体现,各自表中数据不再大量冗余,这才是一种比较清晰的表结构设计。下面我们看代码:
public class Student {
private int id;
private String sName;
private Set<Teacher> teachers = new HashSet<Teacher>(0);
//省略get,set方法
}
public class Teacher {
private int id;
private String tName;
//省略get,set方法
}
这是两张表对应的实体类,下面我们主要看映射文件的配置。
/*配置实体类Student*/
<class name="Student" table="student">
<id name="id">
<generator class="native"/>
</id>
<property name="sName"/>
<set name="teachers" table="connect" cascade="save-update">
<key column="stuId"></key>
<many-to-many class="Teacher" column="tId"/>
</set>
</class>
/*配置实体类Teacher*/
<class name="Teacher" table="teacher">
<id name="id">
<generator class="native"/>
</id>
<property name="tName"/>
</class>
Teacher实体类的配置并没有什么特殊需要解释的地方,而对于Student实体类的配置却稍有变化。其中的set标签就负责创建一张新表并负责关联两张表,table属性就是用于连接两张表主键值的表名(connect)。对于用于连接的表,有两个字段,一个是Student表的id,一个是teacher表的id,那么key标签就用于指定Student表id对应connect表中的名称,teacher表的id对应到connect表的名称则由many-to-many标签的column属性指定。下面我们插入多条数据:
显然,通过抽出connect表连关联两张表,对于Student和teacher表的表结构来说是更加简洁清晰的。
至此,有关Hibernate中关联映射的内容已经简单介绍完毕,虽然以后会更多的使用注解来配置这些映射关联,但是都是基于XML的,对于新手来说,学习XML配置关联映射是有助于理解注解配置。总结不到之处,望指出。
初识Hibernate之关联映射(二)的更多相关文章
- 初识Hibernate之关联映射(一)
上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作.但这都是基于单张表的操作,如果两张或者两张以上的表之间存在某种关联,我们又该如何利用持久化对象进行操作呢?本 ...
- Hibernate注解----关联映射注解以及课程总结详解----图片版本
上一篇,记录了Hibernate注解----类级别注解以及属性注解详解 ,我们这一节主要讲解的是Hibernate注解----关联映射注解以及课程总结详解. 本节的主要内容: 第3章 关联映射注解 3 ...
- Hibernate的关联映射——双向1-N关联
Hibernate的关联映射--双向1-N关联 对于1-N的关联,Hibernate推荐使用双向关联,而且不要让1的一端控制关联关系,而是用N的一端控制关联关系.双线的1-N关联和N-1关联是两种相同 ...
- Hibernate的关联映射——单向1-N关联
Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...
- Hibernate的关联映射——单向1-1关联
Hibernate的关联映射--单向1-1关联 对于单向的1-1关联关系,需要在持久化类里增加代表关联实体的成员变量,并为该成员变量添加setter方法和getter方法.从持久化类的代码上看,单向1 ...
- Hibernate的关联映射——单向N-1关联
Hibernate的关联映射--单向N-1关联 N-1是非常常见的关联关系,最常见的父子关系也是N-1关联,单向的N-1关联只需从N的一端可以访问1的一端. 为了让两个持久化类能够支持这种关联映射,程 ...
- Hibernate之关联映射(一对多和多对一映射,多对多映射)
~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...
- Hibernate的关联映射关系
一:多对一 <many-to-one 1.name:当前类的属性名(关联映射的类) 2.column:属性多对应的类的对应的表的外键(连接条件) 3.class:属性所对应的类的权限定名 4.n ...
- 初识Hibernate之继承映射
前面的两篇文章中,我们介绍了两张表之间的各种相互关联映射关系,但往往我们也会遇到两张表甚至多张表之间共有着多个相同的字段.例如: 如图,student表和teacher表共同具有id,nam ...
随机推荐
- 性能测试中vmstat命令的常见使用。
vmstat是Linux中常用的一个命令,尤其是在进行性能测试时,使用该命令,往往能辅助我们进行性能问题定位. 我们先看一下这个命令执行得到的数据. [root@xxx ~]# vmstat 1 10 ...
- vue-webpack-boilerplate分析
看完这篇文章你会学到通过vue-cli创建的项目,执行npm run dev后都发生了什么事情以及执行流程. 在创建vue项目时,官方推荐使用vue-cli这个命令行工具. # 全局安装 vue-cl ...
- 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍
在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...
- Python中os和shutil模块实用方法集…
Python中os和shutil模块实用方法集锦 类型:转载 时间:2014-05-13 这篇文章主要介绍了Python中os和shutil模块实用方法集锦,需要的朋友可以参考下 复制代码代码如下: ...
- 201521123084 《Java程序设计》第12周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. (1)Java中把不同类型的输入.输出抽象为流(Stream),而其中输入.输出的数据则称为数据流(Data ...
- 201521123073 《Java程序设计》第5周学习总结
1. 本周学习总结 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 1.2 ...
- 201521123007《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 1.1有关继承的知识点: 1.2有关多态 多态性:相同的形态,不同的行为.体现在相同的方法名 ...
- 自定义win8资源管理器左侧导航窗格的方法
Win8自定义资源管理器左侧导航窗格: 快捷键Win+R – 输入regedit: 删除“网络”项目 HKEY_CLASSES_ROOTCLSID{F02C1A0D-BE21-4350-88B0-73 ...
- 201521123077 《Java程序设计》第13周学习总结
1. 本周学习总结 1.1以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 介绍的传输层协议 : TCP 可靠:具有失败重传功能 开销较大:需要建立链路 需要维持传输中的关系 ...
- Java课程设计 购物车系统(个人博客) 201521123052 蓝锦明
1. 团队课程设计博客链接 课程设计团队博客 2. 个人负责模块或任务说明 (1)制作图形菜单引导界面 (2)定义各获取和输出类函数 3. 自己的代码提交记录截图 4. 自己负责模块或任务详细说明 i ...