对象关系 - 多对多

多对多就好比很多学生对应一个课程,每一个学生又对应很多的课程

多对多和多对一在操作上大致相同

重点是:两个表之间的关系,多对多会产生中间表

首先,我们先来讲解一下级联操作

  1. 概述:级联操作

    当对某一类的对象 a 进行操作,如增加、删除、修改时,同时会自动对另一类的某对象 b 进行相同的操作。此时称,对象 a、b 具有级联关系,对象 b 为对象 a 的级联对象。级联操作是通过映射文件的 cascade 属性设置的。

    该属性的值较多,其介绍如下:

    • none:在保存、更新或删除当前对象时,忽略其他关联的对象,即不使用级联。它是默认值。
    • save-update:当通过 Session 的 save()、update()、saveOrUpdate()方法来保存或更新当前对象时,将级联到其他 DB 中的相关联的表。
    • delete:当通过 Session 的 delete()方法删除当前对象时,将级联删除所有关联的对象。
    • all:包含 save-update 及 delete 级联的所有行为。另外,当对当前对象执行 lock()操作时,也会对所有关联的持久化对象执行 lock()操作。
    • delete-orphan:删除所有和当前对象解除关联关系的对象。
    • all-delete-orphan:包含 all 和 delete-orphan 级联的所有行为。
  2. 关联关系维护

    关联关系的维护,也称为外键维护,即为外键字段赋值。Hibernate 默认情况下,关联的双方都具有维护权。即在代码中均可通过调用自己关联属性的 set 方法来建立关联关系。

    反映到数据库中,即是为外键字段赋值。

在 1:n 关系中,例如国家 Country 与部长 Minister 的关系中:

public class Country {
	private Integer cid;
	private String cname;
	//关联属性
	private Set<Minister> ministers;
public class Minister {
	private Integer mid;
	private String mname;
	//关联属性
	private Country country;

Country 对象可以调用自己的 setMinisters()方法来建立关联关系,Minister 也可以调用自己的 setCountry()方法来建立关联关系。

不过,由于外键是建立在多方表 minister 中的,所以对于外键的维护方式,即为外键字段赋值的方式,一方维护与多方维护,其底层执行是不同的。

若关联关系由一方维护,即 Country 对象执行 country.setMinisters(ministers)方法,其实质是 country 对象为 minister 表的外键 countryId 赋值,底层是通过 update 语句来完成的。

底层为什么是通过 update 来完成维护的呢?

country 要主动关联 ministers,则需要在country 对象产生之前,先在 DB 的 minister 表中将即被关联的 minister 先插入完成。此时 DB的表中的 minister 的 countryId 字段值一定为 Null。当 country 对象产生后,需要执行 update语句来修改这个 minister 表的 countryId 的值。

在这里插入图片描述

若关联关系由多方维护,即 Minister 对象执行 minister.setCountry(country)方法,其实质是 minister 对象为自己的表的外键赋值,则可在插入 minister 数据时一并完成,即通过 insert语句来完成。

为什么这里又是通过 inster 语句完成关联关系维护的呢?

minister 要主动关联 country,那么在 minister 出现之前就需要先在 DB 的表中插入完毕将要被关联 country 后,再插入minister。所以,在 Insert 这个主关联对象 minister 的同时,将 countryId 的值也放入了 DB。

多对多2

虽然双方均具有维护权,但一方同时具有放弃维护权的特权。通过对一方关联属性 inverse=“true”设置,即可放弃关联关系维护权,将维护权完全交给多方。

多对多3

猜你喜欢

转载自blog.csdn.net/weixin_43650254/article/details/88616767