前言
本篇主要记录了在一对多关系中,使用inverse和cascade属性。所以,开始的前提条件是有两张一对多的关系表,本篇以用户表和订单表为例。
一、inverse属性的使用
inverse属性是只可以配置在一对多关系中的,那个一的表的映射配置文件中的,直接点来说,就是只能配置在set这个标签中的,对于本篇的例子来说,就是配置在用户表的映射配置文件中的。
inverse属性是用来放弃维护外键的,默认值是false,设置为true,就表示放弃维护外键。
- 默认情况下(false):
Customer customer = new Customer();
customer.setName("Tom3");
Order o1 = new Order();
o1.setName("电脑");
Order o2 = new Order();
o2.setName("鼠标");
customer.getOrders().add(o1); //用户表中关联订单信息
customer.getOrders().add(o2);
o1.setCustomer(customer); //订单关联用户信息
o2.setCustomer(customer);
session.save(customer);
session.save(o1);
session.save(o2);
在这种情况下,会生成5条sql语句,3条insert,还有2条update语句用于更新Order表中的cid。
- 不维护外键(true):
Customer customer = new Customer();
customer.setName("Tom3");
Order o1 = new Order();
o1.setName("电脑");
Order o2 = new Order();
o2.setName("鼠标");
o1.setCustomer(customer); //订单关联用户信息
o2.setCustomer(customer);
session.save(customer);
session.save(o1);
session.save(o2);
在这种情况下,Customer表放弃维护外键,所以customer对象不需要再关联订单,并且,只会生成3条sql语句。
二、cascade属性的使用(级联操作)
1. save-update
级联保存,级联修改(新增用户,并新增订单数据时,只要用户和订单相互关联,保存新增用户操作后,会自动保存相关订单数据)
- 保存(新增):
Customer customer = new Customer();
customer.setName("Tom3");
Order o1 = new Order();
o1.setName("电脑");
Order o2 = new Order();
o2.setName("鼠标");
customer.getOrders().add(o1); //用户表中关联订单信息
customer.getOrders().add(o2);
session.save(customer);
① inverse=true:此时需要手动添加订单与用户的关联(o1.setCustomer(customer)&o2.setCustomer(customer)),否则,在订单表中的cid列,是没有相关用户id的信息的 — 打印3条sql的insert语句。
② inverse=false:代码可以如上图,只需要关联用户与订单 — 打印5条sql语句,3条insert,2条update语句。
(设置了cascade=save-update之后,只需要执行一次session.save(customer))
- 修改:
Customer customer = session.get(Customer.class, 3);
for(Order o:customer.getOrders()){
o.setName(o.getName()+"update2");
}
修改,无论inverse的值设置为哪种,结果都是打印4条sql,一条查询用户,一条查询该用户对应的order,两条修改该用户的订单信息;并且因为查询出来的customer是持久态,所以修改后不需要手动保存。
2. delete
级联删除
Customer customer = session.get(Customer.class, 5);
session.delete(customer);
① inverse=true:删除代码如上,会打印5条sql语句,1条查询用户表,1条查询订单表,2条删除订单,1条删除用户
② inverse=false:删除代码如上,但是会打印6条sql语句,1条查询用户表,1条查询订单表,1条更新订单表,取消订单与用户关联(设置cid为null),2条删除订单,1条删除用户
(如果在customer和order的many-to-one标签中同时设置delete,删除某一订单,就会导致所有订单以及关联用户的删除,所以不可以这么设置)
3. delete-orphan
孤儿删除,解除关联(没有外键引用,会被删除)
Customer customer = session.get(Customer.class, 3);
Iterator<Order> iterator = customer.getOrders().iterator();
while (iterator.hasNext()){
iterator.next();
iterator.remove();
}
inverse设置为默认值false,维护外键,并且查询出用户后,解除用户关联的订单,此时会自动删除订单信息。
4. 其他
all : save-update 和 delete 整合
all-delete-orphan : 三个整合
(因为是前三中的组合形式,具体的情况就不重复写了,这个知道每个值对应哪几种情况的组合就可以了)
总结
本篇主要是记录了两个属性的使用,以及一些简单的小例子,对于这两个属性的设置,主要是要掌握分别设置了什么值的时候,sql语句是如何去执行的。