Hibernate笔记 5:实体关联关系
跳到导航
跳到搜索
关于
数据库中多表之间存在着三种关联关系(一对一、一对多、多对多),用于描述实体数据之间的关系,而这种关系也可以通过对象进行描述。
见:
cascade(级联操作)
“级联操作”:是指当“主控方”执行“保存”、“更新”或者“删除”操作时,其关联对象(“被控方”)也执行相同的操作。 1、在映射文件中通过对 cascade 属性的设置来控制是否对关联对象采用级联操作。 2、级联操作对各种关联关系都是有效的。
级联属性
cascade 属性的可选值:
- all:所有情况下均进行关联操作。【即 save-update + delete】
- none:所有情况下均不进行关联操作。【默认值】
- save-update:在执行 save / update / saveOrUpdate 时进行关联操作。
- delete:在执行 delete 时进行关联操作。
- all-delete-orphan:当一个节点在对象图中成为孤儿节点时,删除该节点。
级联的方向性
级联是有方向性的:
以“一对多”关系为例,“主控方为一端”(通过一端级联操作多端)和“主控方为多端”(通过多端级联操作一端),二者的含义是完全不同的。
示例:
- “双向关联:一对多/多对一”;
- Customer.hbm.xml、LinkMan.hbm.xml 均配置了级联更新“cascade="save-update"”;
@Test // 删除联系人,并级联删除其客户 public void demo() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // 创建一个客户 Customer customer = new Customer(); customer.setCust_name("中国移动"); // 创建三个联系人 LinkMan linkManl = new LinkMan(); linkManl.setLkm_name("老张"); LinkMan linkMan2 = new LinkMan(); linkMan2.setLkm_name("老李"); LinkMan linkMan3 = new LinkMan(); linkMan3.setLkm_name("老王"); //建立关系: linkManl.setCustomer(customer); customer.getLinkMans().add(linkMan2); customer.getLinkMans().add(linkMan3); // 保存 //session.save(linkManl); // 发送几条 insert 语句? //session.save(customer); // 发送几条 insert 语句? //session.save(linkMan2); // 发送几条 insert 语句? tx.commit(); }
如上代码:
- “session.save(linkManl)”:将会产生 4 条 insert 语句;
- 因为:linkManl 关联了 customer;而 customer 又关联了 linkMan2、linkMan3;
- “session.save(customer)”:将会产生 3 条 insert 语句;
- 因为:customer 关联了 linkMan2、linkMan3,但未关联 linkManl;
- (“linkManl 关联了 customer” ≠ “customer 关联了 linkManl”)
- “session.save(linkMan2)”:将会产生 1 条 insert 语句;
- 因为:linkMan2 未关联其他对象;
- (“customer 关联了 linkMan2” ≠ “linkMan2 关联了 customer”)
P.S. “a 关联了 b” ≠ “b 关联了 a”
inverse(关系维护)
inverse 属性用于设置“是否由对方维护关联关系”。 可选值:true / false(默认)
inverse 作用:
- 级联维护:配置为 true 的一方所设置的级联将会失效。
- inverse 的权限在 cascade 之上。
- 外键维护:配置为 true 的一方将不再维护关联的外键字段。
- 维护外键的一方必须拥有对方的实例引用。
外键维护
以双向关联的一对多关系为例。了解 inverse 对外键维护的影响。
有配置如下: