一、一对多关系
表中的表达
实体中的表达
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();
}
级联操作