(Hibernate进阶)Hibernate映射——一对一双向关联映射(六)
上一篇博客我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示:
关键原因在于对象模型具有方向性:
单向:一端只能加载另一端,不能反过来。
双向:两端都可以加载另一端。
问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢?
下面我们开始介绍一对一的双向关联映射。
映射原理
双向关联映射与单向关联映射的原理是一样的,双向关联映射并不影响存储,只影响加载。所以,双向关联映射和单向关联映射的关系模型是一样的即数据库的表结构是一样的,只是IdCard的实体类和配置文件(IdCard.hbm.xml)发生了一点点变化。
对象模型
从上图中可以看出:
1、一个人只有一张身份证,唯一的一个身份证号,对象之间是一对一的关系;
2、两个对象得关系维护还是由person端决定(因为关系只能由一端维护主键,否则关系就乱了)。
根据上面的对象模型,我们可以看到Person端没有变化,但是要在IdCard端加上Person的引用,例如Person和IdCard实体类如下。
Person
- package com.liang.hibernate;
- public class Person {
- private int id;
- private String name;
- private IdCard idCard;
- public IdCard getIdCard() {
- return idCard;
- }
- public void setIdCard(IdCard idCard) {
- this.idCard = idCard;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
IdCard
- package com.liang.hibernate;
- public class IdCard {
- private int id;
- private String cardNo;
- private Person person;
- public Person getPerson() {
- return person;
- }
- public void setPerson(Person person) {
- this.person = person;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getCardNo() {
- return cardNo;
- }
- public void setCardNo(String cardNo) {
- this.cardNo = cardNo;
- }
- }
无论是单向关联映射还是双向关联映射,他们都属于一对一关联映射,只是他们主键的生成策略不同,分为主键关联映射和唯一外键关联映射。
由于它们都属于一对一关联映射,所以,Hibernate封装双向关联映射时,主键关键映射和唯一外键关联映射的加载策略一样,都采用的是一对一<one-to-one name=""></one-to-one>,只是属性设置不一致,所以,下面我们分开来看IdCard的配置文件。
分类:
主键关联映射
同一对一单向关联映射类似,主键关联即利用主键进行关联,关联主键的值相同。下面我们看一下映射文件:
IdCard.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="com.liang.hibernate">
- <class name="IdCard" table="t_idCard">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="cardNo"></property>
- <!-- 怎么加载对象,抓取策略:join联合查询(默认),select:一条条的查询 -->
- <one-to-one name="person" class="Person" fetch="join"></one-to-one>
- </class>
- </hibernate-mapping>
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="com.liang.hibernate">
- <class name="Person" table="t_person">
- <id name="id">
- <!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
- <generator class="foreign" >
- <param name="property">idCard</param>
- </generator>
- </id>
- <property name="name"></property>
- <!--
- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载
- 也就是拿到关系字段值,根据对端的主键来加载关联对象
- constrained="true"表示,当前主键(person的主键)还是一个外键
- 参照了对端的主键(IdCard的主键),也就是会生成外键约束语句
- -->
- <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>
- </class>
- </hibernate-mapping>
生成的表结构
唯一外键关联映射
一对一双向关联映射的外键关联映射也与一对一单向关联映射的外键关联映射类似,在其一对一的指向端(Person)存在一个唯一外键,该唯一外键与被指向端(IdCard)相关联,关联主键的值相同。下面我们看一下映射文件:
IdCard.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="com.liang.hibernate">
- <class name="IdCard" table="t_idCard">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="cardNo"></property>
- <!-- 一对一唯一外键关联双向采用<one-to-one>标签来映射,必须指定<one-to-one>
- 标签中的property-ref属性为关系字段的名称
- -->
- <one-to-one name="person" class="Person" property-ref="idCard"></one-to-one>
- </class>
- </hibernate-mapping>
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="com.liang.hibernate">
- <class name="Person" table="t_person">
- <id name="id">
- <generator class="native" ></generator>
- </id>
- <property name="name"></property>
- <!-- 由于它是一对一的唯一外键关联,它是多对一关联的特例,注释可以直接写成多对一关联-->
- <!-- idCard属性,表达的是本对象与IdCard的多对一关系。 -->
- <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>
- </class>
- </hibernate-mapping>
生成的表结构
对比
一对一单向和双向关联映射的区别正是对象模型和关系模型的区别之一。
对象模型:有方向性。它到底是单向还是双向是由对象模型决定的即配置文件决定。
关系模型:没有方向性或者说是双向的。从任何一端都可以加载另一端。
下载
以上内容,只证明了一对一双向关联映射不影响存储即没有改变表结构,但不能证明关联是双向的,需要写相应的测试用例,我们以源码的形式给大家。源码下载
总结
一对一双向关联映射并不是必须的,是由需求下决定的。如果没有这样的需求,用户也没有要求,系统也不需要,就没有必要建立双向的关联映射。
转:http://blog.csdn.net/jiuqiyuliang/article/details/40384463
(Hibernate进阶)Hibernate映射——一对一双向关联映射(六)的更多相关文章
- 【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)
上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指仅仅能从人(Person)这端载入身份证端(IdCard),可是反过来.不能从身份 ...
- 【SSH系列】hibernate映射 -- 一对一双向关联映射
开篇前言 上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身 ...
- Hibernate一对一双向关联映射
关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介 ...
- 【SSH进阶之路】Hibernate映射——一对一单向关联映射(五)
[SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,採用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例 ...
- Hibernate从入门到精通(六)一对一双向关联映射
在上次的博文Hibernate从入门到精通(五)一对一单向关联映射中我们讲解了一下一对一单向关联映射,这次我们继续讲解一下与之对应的一对一双向关联映射. 一对一双向关联 与一对一单向关联映射所不同的的 ...
- Hibernate(六)一对一双向关联映射
在上次的博文Hibernate从入门到精通(五)一对一单向关联映射中我们讲解了一下一对一单向关联映射, 这次我们继续讲解一下与之对应的一对一双向关联映射. 一对一双向关联 与一对一单向关联映 射所不同 ...
- (Hibernate进阶)Hibernate映射——一对一单向关联映射(五)
映射原理 两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应.例如:一个人(Person)只有一张身份证(IdCard).我们看一下这个例子的对象模型,如下图所示: 对象模型 ...
- 【SSH系列】Hibernate映射 -- 一对一单向关联映射
映射原理 一对一关联映射:两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应.有两种策略可以实现一对一的关联映射: a.主键关联:即让两个对象具有相 ...
- Hibernate(五)一对一单向关联映射
上次的博文中 Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来 我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理 多个相关 ...
随机推荐
- C# 模拟按下回车键自动登录
private void Form1_Load(object sender, EventArgs e) { //this.Show(); this.Activate(); //this.Focus() ...
- android 观察者模式
1:观察者模式: 1:使用场景:一般使用在自定义控件的事件点击监听上面(或者封装方法进行回调) 2:写观察者模式步骤: (1):声明一个接口 (2):接口里面封装一个抽象方法 (3):需要封装一个 ...
- c# foreach循环二维数组
假设已有二维数组 array 行4, 列4for(int i=0;i<4;i++)//行的行数{ for(int j=0;j<4;j++)//行的列数 { console.wrie( ar ...
- Python-Mac 安装 PyQt4
环境: 系统: OS X 10.11.4 Python: 2.7.10 1.安装 Qt brew install qt 测试安装结果,需要正确找到 qmake 的路径 qmake 2.安装 SIP 下 ...
- DBA-mysql-字符集
查看支持的字符集:show charset; 查看现使用字符集:status; 1.在[mysqld]下添加 default-character-set=utf8 (mysql 5.1版本) char ...
- 入侵本地Mac OS X的详细过程 转自https://yq.aliyun.com/articles/22459?spm=5176.100239.blogcont24250.10.CfBYE9
摘要: 本文从提升权限漏洞的一系列巧妙的方法来绕过受保护的Mac OS X.有些已经被处于底层控制,但由于它们存在着更多的认证和修补程序,我们不妨让这些提供出来,以便需要的人学习它们.虽然我不只是要利 ...
- centos 7安装部署docker
1.centos 7 在windows下通过vm虚拟机安装centos 7: VMware-workstation-full-10.0.3-1895310 centos 7 2.要求 操作系统的内核版 ...
- 初级文法课程-第1课:名词的种类/名词的数/名词的所有格/冠词;be 动词、一般动词的现在式
January 31, 2016 Unit 1 名词和冠词 名词:n (noun) 作用:当主词.补语.受词 1.名词的种类 [单数和复数--I like dogs] 普通名词:book,pen ...
- linux shell:nginx日志切割脚本
需求原因:nginx不具备日志切割功能,日志量较大,方便分析. 实现目的:完成nginx日志切割,并根据时间命名 简要命令: mv /usr/local/tengine/logs/access.l ...
- Lua学习---Lua的控制结构
前言 由于之前有c/c++.javascript基础,所以学Lua的时候喜欢拿来和前面的语言比较,这里主要和C比较 1.if...else Lua的if语句格式: if 条件 then 条件成立,运行 ...