Hibernate的关联关系映射

1、级联操作

级联操作是通过映射文件的 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。

 

3、预处理语句

所谓预处理语句,即该语句当前先产生,但暂时不执行,等后面条件成熟,或程序运行完毕再执行的语句。

当一方具有关联关系的维护权,并且执行 save(一方对象)时,会产生一条 update 预处理语句,用于维护外键值。那么,为什么这个 update 为预处理语句,而不是立即执行的呢?因为该语句所要 update 的这条多方表中记录还未被插入,即还不存在。只有当这个多方对象也 insert 完毕后,即在多方表中出现这条记录时,才会引发预处理语句 update 的执行,将多方表中的外键字段值填上。

当多方具有关联关系的维护权,并且执行 save(多方对象)时,会产生一条 insert 预处理语句,用于维护外键值。那么,为什么这个 insert 也为预处理语句,而不是立即执行的呢?因为该语句所要 insert 的这条多方数据,其所关联的一方对象还未被插入,即还不存在。所以其外键字段值还未出现。只有当这个一方对象也 insert 完毕后,即在一方表中出现这条记录时,才会引发对多方对象的预处理语句 insert 的执行,将多方表中的外键字段值同多方表中的其它普通属性值一同插入。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值