搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
我家小花儿
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
[GO专栏-1]Go语言的前生今世_robert griesemer
2
为什么我建议你多做数据仓库项目
3
算法练习之双指针算法
4
stm32 MPU6050 姿态解算 Mahony互补滤波算法_mahony算法
5
SMALI语法大全
6
FaceShifter:一秒换脸的人脸交换模型
7
MPLS VP Hub and Spoke实验_hub-ce 和hub-pe
8
Android 查看项目依赖关系_android windows查看依赖so
9
数据安全现状与发展趋势研究
10
如何查看CSDN博客的积分与对应的权益_csdn博客等级积分在哪看
当前位置:
article
> 正文
【JPA】@OneToOne 一对一双向关联注解_@onetoone注解
作者:我家小花儿 | 2024-05-03 18:19:42
赞
踩
@onetoone注解
原文请点击此处
@OneToOne 定义:一对一关系。
这次,我们引用一个新的数据模型:丈夫(
husband
) 和 妻子(wife)。前提:众所周知,在我们伟大的祖国,法律上只存在一种婚姻关系,一夫一妻制。所以,一个丈夫只能有一个妻子,一个妻子也只有一个丈夫。(大家千万别较真,我已经限定了场景,法律上只允许一夫一妻。小三不在本例研究范围内)
对于这种数据模型来说,双向一对一关系已经很明显了。我们通过丈夫应该能找到他的妻子。同样,通过妻子,应该能找到她的丈夫。
好了,让我们来看例子吧:
@Entity
@Table(name = "husband")
public class Husband (){
@Id
//JPA注释:
主键
@GeneratedValue(strategy = GenerationType.AUTO)
//设置 id 为自增长
private Long id;
private String name;
//由于,husband 是这个一对一的关系的主控方,所以,在
husband
表中添加了一个 wife 的外键。
//通过这个外键来维护 people和pet的一对一关系,而不是用第三张码表。这个是通过
@JoinColumn注释实现的。
@OneToOne
//JPA注释:
一对一 关系
@JoinColumn(name="wife_fk" )// 在husband中,添加一个外键
"
wife_fk
"
private Wife wife;
//省略 get / set
方法...
}
@Entity
@Table(name = "wife")
public class Wife (){
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
//注意:由于是双向的一对一关系。作为关系的被维护端。需要在wife实体中添加和 husband 关联的属性
//mappedBy 注释:指定了,这个实体是被关系维护端的那个属性所维护。
//在本例中,Wife实体是被 Hhusband实体中的外键“wife”所维护。
@OneToOne(mappedBy="wife")
private Husband husband;
//省略 get / set
方法...
}
那么,现在已经很明显了。在Wife 的 Model 中,已经找到了与 Husband 关联的属性了。但是,如果进入到数据库中查看Wife这张表,你并不会在表里找到关联到
Husband的外键。为什么会这样呢?因为,我们定义关系的时候,规定了关系的维护端是Husband。所以,只有Husband中有管理到Wife的外键。而这个一对一关系,就是靠这个外键来维护的。那当我们设置了,mappedBy后,使关系成为双向的时候,是怎样通过Wife实体来得到她对应的Husband实体的呢?这都是由JPA来做的。我们不必在这上面花费过多的精力。如果,你感兴趣,也可以自己研究思考一下。
-----------------------------------------测试--------------------------------------------------------------------------
测试方法:
//省略包的引用:HusbandDao , WifeDao
public class TestOneToOneEitherSide() {
//测试方法1-------创建实体:丈夫 和 妻子
public void testCreate() {
Husband wang = new Husbnad();
wang.setName("老王");
Wife li = new Wife();
li.setName("莉莉");
//由于关系是双向的,所以,你不必手动的来设置“
莉莉
”的丈夫。JPA会自动完成这个操作。所以,即使将这个操作注释掉,双向关系还是会正确的建立的。
//wife.setHusband(wang);
wifeDao.save(li);
//将“莉莉” 交给 “老王”。
//但是,这一步,就不可以省略了。必须得手动的或者说显式的设置“老王”和“莉莉”的关系。如果,你省略了这一步,那么就没法建立起 “老王” 和 “莉莉” 的你一对一关系了,无论是双向的还是单向的。
wang.setWife(li);
//此时,老王 和 莉莉 ,已经是双向的一对一关系了。通过他俩任何一方,都可以找到另一个对象。
husbandDao.save(wang);
//验证方法1:
//在表 Husband 中找到名字是老王的丈夫。
Husband husband = husbandDao.findByName("老王");
//通过老王得到他的妻子实体,并调用妻子的getName()方法,得到老王妻子的姓名。
Wife wangWife =
husband.getWife();
String wifeName =
wangWife
.getName();
System.out.println(
wifeName
);//结果为: 莉莉
//验证方法2:与方法1类似,简写。
Wife wife = wifeDao.findByName("莉莉");
String husbandName = wife.getHusband().getName();
System.out.println(
husbandName
);//结果为: 老王
//通过这两个验证方法,我们已经知道,在设置了双向一对一关系后。我们已经可以通过关系的一方,得到与之对应的另一方了。其实,双向的实际使用意义也正是如此。通过关系的任意一方可以得到与之对应的另一方
}
//测试方法2-------删除实体:丈夫
public void testDeleteHusband() {
//在表 Husband 中找到名字是老王的丈夫。
Husband wang = husbandDao.findByName("老王");
//校验空值和空对象的方法省略,因为肯定会得到老王这个实体的。
husbandDao.delete(
wang
);
//验证方法1:
//在表 Husband 中找到名字是老王的丈夫。
Husband husband = husbandDao.findByName("老王");
System.out.println(
husband
);//结果为: 空(null)
//验证方法2:与方法1类似,简写。
Wife wife = wifeDao.findByName("莉莉");
if(wife != null){
Husband wifeHusband = wife.getHusband();
System.out.println(
wifeHusband
);//结果为: 空(null)
}
//名字叫“老王”的丈夫已经被顺利的删除掉了。没有报异常,他的妻子“莉莉”并没有被一同删掉。(因为没有添加级联删除的原因)。此时,我们发现“莉莉”的丈夫属性也是空的。老王这个关系的维护端被删除的时候,JPA会做相应的操作,并不会影响到“莉莉”。表Wife中本来也没有与Husband 关联的外键,删除 老王,当然不会对 莉莉 产生影响了。因为
她的丈夫属性上有mappedBy 注释。
}
//测试方法3-------直接删除实体:妻子
//这种直接删除的方式,会产生异常
public void testDeleteWife() {
//得到名字是“莉莉”的实体
Wife li = wifeDao.findByName("莉莉");
wifeDao.delete(li);
//此时后台会报异常,数据库回滚,无法删除"莉莉"
}
-------------------------------------------------------------------------------------------------------------------
假设,数据库没有回滚,那么莉莉删除掉后。在表 Husband 中,老王这个实体的 外键 还是 "莉莉" 的id。但是,此时,莉莉已经被删除掉了。这样当然会产生异常。在上一篇帮助手册
【JPA】 @OneToOne 单向
中,我们曾经遇到过这种情况。删除关系被维护端之前,没有从关系维护端手动解除关系,后台就一定会报异常。在任何关系中,都是这样,不论他是单向的还是双向的,不论是一对一、一对多、多对多。只要想删除关系的被维护端,必须先从关系的维护端手动解除关系。
在看正确的删除被维护端方法前,我们应该回忆一下,在
【JPA】 @OneToOne 单向
中,删除关系被维护端是一件多么痛苦的事儿啊。我得通过循环去 关系维护端所在的表中,找到要删除的实体对应的维护端。但是,在双向的 一对一 关系中。找到实体的维护端,好像并不是一件痛苦的事儿。
-------------------------------------------------------------------------------------------------------------------
//测试方法4-------解除关系并删除实体:妻子
//正确的删除方法
public void rightDeleteWife(){
//得到名字是“莉莉”的实体
Wife li = wifeDao.findByName("莉莉");
//得到她的关系维护端,也就是她的丈夫
Husband liHusband = li.getHusband();
//此时,我们要强迫 “老王” 解除 他和 “莉莉” 的关系
liHusband.setWife(null);
wifeDao.delete(li);
//验证方法:
Husaband wang = husbandDao.findByName("老王");
Wife wangWife = wang.getWife();
//当存在老王这个实体,并且老王没有妻子时,打印我们的校验信息
if(
wang
!= null
&&
wangWife == null
){
System.out.println(
"老王单身了"
);
}
//果然,这句话被打印出来了。莉莉 被成功的删除掉了,老王的外键也被置空了。看来,想要删除被维护端,只能手动的先从关系维护端解除关系再删除。
}
===============================================================
至此,一对一关系,已经向大家全部介绍完毕了。其实,建立一对一关系,还有别的方法。比如共享主键之类的。但是,用这两篇文章的方法建立一对一关系比较方便,也不会产生第三张码表。数据库比较干净。如果,大家对另外两种建立方法感兴趣,可以自己查看我们翻译的中文API。这里就不做阐述了。
这两篇文章,都强调了关系被维护端的删除操作。就是想让大家重视,关系的维护端的作用和删除操作易发生的异常。至于级联操作,由于大家刚刚熟悉关系,所以,稍后会在 @OneToMany(
一对多
) 关系中,向大家慢慢阐述。而且,级联操作,在一对多关系中的作用比较大。但是,一定要慎用,否则会产生你意料不到的麻烦。请期待
【JPA 级联保存/级联删除】@OneToMany 一对多(单向和双向)注解
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/我家小花儿/article/detail/530955
推荐阅读
article
SpringBoot-
SpringData
-
oneToOne
_
spring
data
onetoon...
前面说了SpringBoot-
SpringData
-JPA集成 以这个项目为基础,继续
SpringData
的一些功能下面...
赞
踩
article
jpa
onetoone
_
Spring
Data
JPA关系映射@
OneToOne
...
@
OneToOne
, 表示一对一的映射关系,比如一个账号对应一个用户,一个实体用来描述账号的信息(账号,密码,账号是否可...
赞
踩
article
JPA
关系
映射
(
OneToOne
、
OneToMany
、
ManyToMany
)_jpa onetoo...
单向
OneToOne
单向一对一是关联
关系
映射
中最简单的一种,简单地说就是可以从关联的一方去查询另一方,却不能反向查询。...
赞
踩
article
Mybatis
一对
多(
OneToOne
)关系映射
_
mybatisplus
onetoone
...
标签:
Mybatis
一对
多(
OneToOne
)关系映射 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出...
赞
踩
article
Hibernate
@
OnetoOne
注解_
@
onetoone
(
optional
=
false
)...
@
OneToOne详解_
@
onetoone
(
optional
=
false
)
@
onetoone
(
optional
= ...
赞
踩
article
JPA @
OneToOne
@OneToMany @ManyToOne @ManyToMany 描述...
JPA 四种关系描述@
OneToOne
@OneToMany@ManyToOne@ManyToMany@
OneToOne
@...
赞
踩
article
JPA
#
OneToOne
...
无力吐槽。一对一,一个人有一个身份证号码、一个人有一条命,类似于这一种的就是一对一的关系。涉及到的注解两个:OneToO...
赞
踩
article
JPA 使用
@
OneToOne
_
jpa
onetoone
...
OneToOne
,就是一对一映射,现实生活中比较常见的例子就是一个人有一个身份证,一个丈夫只能有一个老婆新建一个Pers...
赞
踩
article
Spring
JPA 联表
查询
之
OneToOne
_
jpa
onetoone
find
实体字段...
前面几篇我们学习的都是单表
查询
,就是对一张表中的数据进行
查询
。而实际项目中,基本都会有多张表联合
查询
的情况,今天我们就来...
赞
踩
article
JPA
@
OneToOne
使用_
jpa
onetoone
...
产品迭代引入
JPA
,记录一下初次使用 @
OneToOne
和遇到的坑。纯实操内容。_
jpa
onetoone
jpa
one...
赞
踩
article
jpa
onetoone
_
Spring
JPA
关系
映射系列教程:
OneToOne
关系
映射详解...
这是
JPA
关系
映射 系列教程的第一篇:
JPA
One-To-One 外键
关系
映射
JPA
关系
映射系列(SPring B...
赞
踩
article
JPA 中
OneToOne
单向级联,实现两个实体
更新
_
jpa
@
onetoone
case
...
折腾了一上午,终于搞定了。 一、有两个实体对象,“任务实例(KuWfRuProcInst)”和“任务实例表单数据(KuW...
赞
踩
article
【
JPA
】 @
OneToOne
一对一
单向
关联
注解
_
jpa
注解
一对一
...
原文请点击此处 @
OneToOne
定义:
一对一
关系。 生活中的
一对一
关系,举例:人(man) 和 宠物(pet)。前...
赞
踩
article
JPA总结——实体关系映射(
一对一
@
OneToOne
)_
jpa
@
onetoone
单向
关联
...
一对一
(@
OneToOne
)· 单向
关联
# 注释@
OneToOne
定义如下:@Target({METHOD, FIELD...
赞
踩
相关标签
SpringData
SpringBoot
oneToOne
数据库
jpa onetoone
JPA
Hibernate
关系映射
OneToOne
OneToMany ManyToMany
hibernate
java
spring
json
后端
开发语言
jpa
J2ee
一对一
更新