Hibernate——一对多,多对多关系
一、一对多关系
表中的表达
实体中的表达
ORM元数据配置
1)一对多配置
2)多对一配置
操作关联属性
1、添加客户,添加联系方式
@Test public void func1() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------- // 1.实例化客户实体 Customer c = new Customer(); c.setCust_name("鑫哥论文"); // 2.实例化联系人 LinkMan lm1 = new LinkMan(); lm1.setLkm_name("xxx"); LinkMan lm2 = new LinkMan(); lm2.setLkm_name("jasonyu"); // 3.获取客户对象中的集合,添加进去 c.getLinkMens().add(lm1); c.getLinkMens().add(lm2); // 4.设置外键 lm1.setCustomer(c); lm2.setCustomer(c); session.save(c); session.save(lm1); session.save(lm2); //---------------------------------------- tx.commit(); session.close(); }
2、只添加联系人
@Test public void func2() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------- // 1.获取要操作的客户对象 Customer customer = session.get(Customer.class, 1L); // 2.实例化新联系人 LinkMan lk3 = new LinkMan(); lk3.setLkm_name("张宝岩"); // 3.为客户对象中的联系人集合中添加新的联系人 customer.getLinkMens().add(lk3); // 4.将联系人中的custom属性设置为 客户对象 lk3.setCustomer(customer); // 5.保存联系人对象(不用保存客户对象) session.save(lk3); //---------------------------------------- tx.commit(); session.close(); }
3、清除某个联系人的外键关联
@Test public void func3() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------- // 1.获取要操作的客户对象 Customer customer = session.get(Customer.class, 1L); // 2.获取要操作的联系人 LinkMan lk = session.get(LinkMan.class, 2L); // 3.将联系人从客户对象中的联系人集合移除 customer.getLinkMens().remove(lk); // 4.将联系人的customer设置为null*** lk.setCustomer(null); //---------------------------------------- tx.commit(); session.close(); }
4、直接删除联系人
@Test public void func4() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------- // 1.获取要操作的客户对象 Customer customer = session.get(Customer.class, 1L); // 2.获取要操作的联系人 LinkMan lk = session.get(LinkMan.class, 2L); // 3.将联系人从客户对象中的联系人集合移除 customer.getLinkMens().remove(lk); // 4.将联系人的customer设置为null*** session.delete(lk); //---------------------------------------- tx.commit(); session.close(); }
级联操作
元数据配置文件
<!-- 级联操作: cascade save-update: 级联保存更新(只save一个表的实例,另一个关联表的实例也save) delete:级联删除(删除一个表的,另一个关联表的相应字段也被删除) all:save-update+delete 级联操作: 简化操作.目的就是为了少些两行代码. --> <set name="linkMens" cascade="save-update" > <key column="lkm_cust_id" ></key> <one-to-many class="LinkMan" /> </set>
结论: 简化操作.一定要用save-update,不建议使用delete.
关系维护
在保存时.两方都会维护外键关系,关系维护两次,冗余了;多余的维护关系语句,显然是客户这一端在维护关系
<!-- inverse属性: 配置关系是否维护. true: customer不维护关系 false(默认值): customer维护关系 inverse属性: 性能优化,提高关系维护的性能. 原则: 无论怎么放弃,总有一方必须要维护关系. 一对多关系中: 一的一方放弃,也只能一的一方放弃,多的一方不能放弃. --> <set name="linkMens" inverse="true"> <key column="lkm_cust_id" ></key> <one-to-many class="LinkMan" /> </set>
二、多对多关系
表中关系表达
实体中表达
元数据配置
普通操作
1、添加职位和职员
@Test public void func1(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // ---------------------------------------- // 1.获取两个Role 职位对象 Role r1 = new Role(); r1.setRole_name("保洁"); Role r2 = new Role(); r2.setRole_name("保安"); // 2.获取两个User 职员对象 User u1 = new User(); u1.setUser_name("计震宇"); User u2 = new User(); u2.setUser_name("张宝岩"); // 3.将2个用户送进两个职位下的用户列表中 r1.getUsers().add(u1); r1.getUsers().add(u2); r2.getUsers().add(u1); r2.getUsers().add(u2); // 4.将两个职位送入2个用户下的职位列表中 u1.getRoles().add(r1); u1.getRoles().add(r2); u2.getRoles().add(r1); u2.getRoles().add(r2); // 5.保存 session.save(u1); session.save(u2); session.save(r1); session.save(r2); // ---------------------------------------- tx.commit(); session.close(); }
这种平常不过的操作,会报错,因为双方都维护第三张表,这样就维护了两次,所以我们要使用inverse属性,让一方放弃维护
2、为计震宇添加一个职位
@Test public void func1(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // ---------------------------------------- // 1.获取新Role 职位对象 Role role = new Role(); role.setRole_name("男公关"); // 2.获取计震宇角色 User user = session.get(User.class, 1L); // 3.将计震宇放进新职位 user.getRoles().add(role); // 4.将新职位放进计震宇 role.getUsers().add(user); // 5.保存(如果开启了级联操作,这句可以省略) session.save(role); // ---------------------------------------- tx.commit(); session.close(); }
3、为计震宇解除一个角色
@Test public void func1(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // ---------------------------------------- // 1.获取要解除的Role 职位对象 Role role = session.get(Role.class, 2L); // 2.获取计震宇角色 User user = session.get(User.class, 1L); // 3.将职位从列表找中移除 user.getRoles().remove(role); // 4.将计震宇从职位下的员工列表中移除(开启级联可以省略这句) role.getUsers().remove(user); // ---------------------------------------- tx.commit(); session.close(); }
级联操作