Spring Data JPA-双向一对一关联映射
如果一个男孩和一个女孩相爱,那么她们的心里只能装着对方一个人,不能脚踏好几只船……
通过上面描述,我们明白这是一个双向的关联关系,而且都是一对一。这个和我前面讲过单向一对一十分类似。
甜美的爱情故事,生死相依
小红和小明的一段神话般的甜美爱情故事:有一天,小红问他男朋友小明:你心里有没有我?小明睁着眼睛说:当然了,心里满满的都是你。小明紧接着就反问他的女朋友小红:臭宝,你心里是不是也满满都是我?小红睁着眼睛回答说:当然了。
小红和小明,相互依赖,永不分离……
男孩domain
@Entity
@Table(name = "tb_boy")
@Getter
@Setter
public class Boy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String boyName;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "girl")
private Girl boyHeart;
}
女孩domain
@Entity
@Table(name = "tb_girl")
@Getter
@Setter
public class Girl {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String girlName;
@OneToOne
@JoinColumn(name = "boy")
private Boy girlHeart;
}
Repository:相当于他们的爱情,没有它就无法相互操控彼此的内心(数据)
public interface BoyRepository extends JpaRepository<Boy, Long> {
}
public interface GirlRepository extends JpaRepository<Girl, Long> {
}
这个男孩主动追求这个女孩并向她表白,起初只有男孩的心里装着这个女孩,后来经过男孩一顿猛如虎的操作,女孩爱上了男孩,这时两人都将彼此装在了心里……
@Test
public void testInsert() {
// 初始化数据
Boy boy = new Boy();
boy.setBoyName("小明");
Girl girl = new Girl();
girl.setGirlName("小红");
// 将对方都装在心里
boy.setBoyHeart(girl);
girl.setGirlHeart(boy);
boyRepository.save(boy);
}
日志输出
Hibernate: insert into tb_girl (boy, girl_name) values (?, ?)
Hibernate: insert into tb_boy (girl, boy_name) values (?, ?)
Hibernate: update tb_girl set boy=?, girl_name=? where id=?
数据库
可以看到,他们相互都装着对方。
上面这样做会出现一个问题就是:这两张表你都删不掉,数据你也删不掉,因为两张表中相互依赖了外键,除非你把外键解除了。
这是一个甜蜜的爱情故事,相互相依永不分离。
凄惨的爱情故事,合久必分
小红和小明的一段凄惨的爱情故事:有一天,小红问他男朋友小明:你心里有没有我?小明闭着眼睛说:当然了,心里满满的都是你。小明就反问他的女朋友小红:臭宝,你心里是不是也满满都是我?小红睁着眼睛回答说:当然了。
通过上面一段凄惨的爱情故事我们知道,男孩是个渣男,她心里根本没有女孩,因为女孩问男孩时男孩是闭着眼睛回答的……
女孩domain
@Entity
@Table(name = "tb_girl")
@Getter
@Setter
public class Girl {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String girlName;
@OneToOne
@JoinColumn(name = "boy_heart")
private Boy girlHeart;
}
男孩domain
@Entity
@Table(name = "tb_boy")
@Getter
@Setter
public class Boy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String boyName;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "girlHeart")
@JoinColumn(name = "girl")
private Girl boyHeart;
}
这个男孩主动追求这个女孩并向她表白,同样经过男孩一顿猛如虎的操作,女孩爱上了男孩,女孩的心里从此多了个男孩,但是男孩心里没有女孩,男孩只是想……
@Test
public void testInsert() {
// 初始化数据
Boy boy = new Boy();
boy.setBoyName("小明");
Girl girl = new Girl();
girl.setGirlName("小红");
// 将对方都装在心里
boy.setBoyHeart(girl);
girl.setGirlHeart(boy);
boyRepository.save(boy);
}
日志输出
Hibernate: insert into tb_boy (boy_name) values (?)
Hibernate: insert into tb_girl (boy, girl_name) values (?, ?)
数据库
可以看到,这时男孩心里并没有女孩。
上面这样做也会出现一个问题:这两张表中其中有一张表会依赖另一张表的主键。也就是说,只要男孩提分手,女孩立马同意分手,而且女孩没有主动权,这是一个凄惨的爱情故事,啊呸!
双向一对一操作中,查询任意一方都可以查询出另一方的信息,哪怕有一方没有维护外键。