在上一篇简单总结了一级缓存,快照,增删改查的简单使用,这一篇总结两张表的级联操作。
级联涉及到三种情况,many-many,1-many,many-1。
- 首先是1-many,many-1情况,所以先设置一个情景:客户与订单的关系
//因为太占版面缘故,没有列出get()/set()方法public class Customer { private Integer id; private String name; private Setorders = new HashSet ();//1对多}public class Order { private Integer id; private String name; private Customer customer;//多对1}
接下来是hibernate.cfg.xml与两个实体类的配置文件Order.hbm.xml与Customer.hbm.xml,第一个不多说,主要是映射文件的配置
//Customer.hbm.xml//Order.hbm.xml
一切准备就绪,开始级联的代码:
因为代码中大量使用了得到连接,关闭连接操作,所以我使用了模板设计模式,在我的文章《》有讲解
/** * 级联保存: * 1.inverse="true",维护关系,最好只有一方维护,而且是拥有外键一方维护 * 2.cascade="save-update",级联保存与级联更新 */ @Test public void test0() { new SessionTemplate(){ @Override public void fun(Session s) { Customer c=new Customer(); c.setName("King"); Order o1=new Order(); o1.setName("炒面"); Order o2=new Order(); o2.setName("肉"); o1.setCustomer(c);//由拥有外键一方维护关系 o2.setCustomer(c); s.save(c); s.save(o1); s.save(o2);//这样框架只执行了3条SQL语句 } }.execute(); }
/** * 级联删除: * 1.inverse="false"为默认处理方式:把客户的订单的外键修改为null,然后再删除客户 * 2.inverse="true"若客户不处理,会出错 */ @Test public void test1() { new SessionTemplate(){ @Override public void fun(Session s) { //这是没有使用级联删除的情况,这时cascade为save-update Customer c=(Customer) s.get(Customer.class, 3); for(Order o:c.getOrders()){ s.delete(o); } s.delete(c);//此时,inverse="true",所以前面删除了所有客户的订单才能删除客户 //更改配置文件,cascade为delete,这时就是级联删除
Customer c=(Customer) s.get(Customer.class, 3); s.delete(c);//这时不需要手动删除订单了
} }.execute(); }
/** * 级联更新 * cascade为save-update */ @Test public void test2() { new SessionTemplate(){ @Override public void fun(Session s) { Customer c=(Customer) s.get(Customer.class, 2); for(Order o:c.getOrders()){ o.setName("羊杂汤");//持久态,不需要更新 } } }.execute(); }
查询涉及到了加载策略,所以很复杂,所以将在写在下一篇中。
- 接下来说many-many的情况,还是先设置一个情景:学生与课程的关系
public class Student { private Integer id; private String name; private Setcourses=new HashSet<>();//多对多}public class Course { private Integer id; private String name; private Set students=new HashSet<>();//多对多}
接下来是两个实体类与数据库表的映射文件:
//Student.hbm.xml//Course.hbm.xml
一切准备继续,开始代码工作:
/** * 多对多 * 级联保存: * 本来想也写上级联删除与级联更新,但是发现写的代码和我想要实现的结果不同,故没有贴出代码,额...我的意思就是我也不会...挺尴尬... */ @Test public void test0() { new SessionTemplate(){ @Override public void fun(Session s) { Student s1=new Student(); s1.setName("King"); Course c1=new Course(); c1.setName("数学"); Course c2=new Course(); c2.setName("英语"); s1.getCourses().add(c1);//由学生维护关系 s1.getCourses().add(c2);//由学生维护关系 s.save(s1); } }.execute(); }
增删改查,现在就差“查”没有写出,我将在下一篇总结中写出Hibernate的关于查询的加载策略。