-----------------一对多,多对一
- 级联在两方中都可以,但是只能同时有一家配置
- 多对一重点是双方关系互相保存,如果在一和多的实体对象相互关联之后想要只保存一的部分使多的部分自动保存则需要配置级联 cascade字段
-------------原始相互关联,相互保存
--------------------------保存客户及其联系人
Customer c = new Customer();
c.setCust_name("aaa");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("bbb");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name("ccc");
//表达一对多,客户下有多个联系人
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2);
//表达对对对,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
session.save(lm1);
session.save(lm2);
//-------------------------------------------------获得客户添加联系人
Customer c = session.get(Customer.class,1l);
//2> 创建联系人
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("ddd");
//3> 将联系人添加到客户,将客户设置到联系人中
c.getLinkMens().add(lm1);
lm1.setCustomer(c);
//4> 执行保存
session.save(lm1);
------------------------------删除客户及其联系人
Customer c = session.get(Customer.class,1l);
//2> 获得要移除的联系人
LinkMan lm = session.get(LinkMan.class, 3l);
//3> 将联系人从客户集合中移除
c.getLinkMens().remove(lm);
lm.setCustomer(null);
--------------------原始的需要保存两次,晋级的在元配置文件中一的部分加入cascade字段则只需要保存一的部分省略保存多的部分-----级联
----------- 省略保存联系人(多)的部分cascade:save-update
session.save(c);
// session.save(lm1);
// session.save(lm2);
----------------级联删除客户下的联系人cascade:delete
Customer c = session.get(Customer.class,1l);
//2>调用delete删除客户
session.delete(c);
---------
- 元配置和主配置文件是对应的,多加一个元配置主配置文件就要多一条
<mapping resource="cn/itcast/domain/Customer.hbm.xml" />
<mapping resource="cn/itcast/domain/LinkMan.hbm.xml" />
- 元配置文件中一定保证多对一,一对多的column是一样的
- 表中表达是在多中引入外键表达属于哪个一
- 实体中表达是在一中引入set(map多一个外键,list可重复不选)包含多,在多的实体一方引入一的实体对象以作关联
- char-Charset;varchar-String
//表达多对一关系
private Customer customer ;
---------------------------------------------
//使用set集合,表达一对多关系(初始化)
private Set<LinkMan> linkMens = new HashSet<LinkMan>();
----------------------------------元素实体中一的一方是多一个set,配置文件需要多,注意class如果page没配置需要写全类名而不能简化
<!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名 -->
<!--
级联操作: cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码. -->
<!-- inverse属性: 配置关系是否维护.
true: customer不维护关系
false(默认值): customer维护关系
inverse属性: 性能优化.提高关系维护的性能.
原则: 无论怎么放弃,总有一方必须要维护关系.
一对多关系中: 一的一方放弃.也只能一的一方放弃.多的一方不能放弃.
-->
<set name="linkMens" inverse="true" cascade="delete" >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>
-----------------------------------多对一配置引入的对象
<!-- 多对一 -->
<!--
name属性:引用属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<!--
级联操作: cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码.
-->
<!-- 多的一方: 不能放弃维护关系的.外键字段就在多的一方. -->
<many-to-one name="customer" column="lkm_cust_id" class="Customer" >
</many-to-one>
-----------------多对多
- 代码中保存和配置文件是互相搭配使用,仅设置一方会出现错误
--------------user.hbm.xml
<!-- 多对多关系表达 -->
<!--
name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用比人的外键列名
-->
<!-- cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除
结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.
-->
<set name="roles" table="sys_user_role" cascade="save-update" >
<key column="user_id" ></key>
<many-to-many class="Role" column="role_id" ></many-to-many>
</set>
---------------------role.hbm.xml
<!-- 使用inverse属性
true: 放弃维护外键关系
false(默认值):维护关系
结论: 如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向(由不确定一方进行维护). 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护
-->
<set name="users" table="sys_user_role" inverse="true" >
<key column="role_id" ></key>
<many-to-many class="User" column="user_id" ></many-to-many>
</set>
-------------每增加一条元配置文件需要在主配置文件中添加关联
<mapping resource="cn/fb/domain/Role.hbm.xml" />
--------------------text实体之间相互关联仅保存一方(都保存也可),保存只保存不确定一方(但在配置中有cascade属性代替)并且需要放弃维护一方因为都维护会在第三张关系表中插入相同数据(一对多不会出现类似是因为插入的字段可以重复修改)
// 多对多添加
Role r1 = new Role();
r1.setRole_name("保洁");
Role r2 = new Role();
r2.setRole_name("前台");
User u1 = new User();
u1.setUser_name("张三");
u1.getRoles().add(r2);
u1.getRoles().add(r1);
User u2 = new User();
u2.setUser_name("李四");
u2.getRoles().add(r1);
sess.save(u1);
sess.save(u2);
----------------获得用户新增角色
User user = session.get(User.class, 1l);
//2> 创建公关角色
Role r = new Role();
r.setRole_name("男公关");
//3> 将角色添加到用户中
user.getRoles().add(r);
//4> 将角色转换为持久化
//session.save(r);
---------------删除用户一个角色,同样需要获得角色实体对象,然后在相应集合删除
User user = session.get(User.class, 1l);
//2> 获得要操作的角色对象(保洁,保安)
Role r1 = session.get(Role.class, 1l);
Role r2 = session.get(Role.class, 2l);
//3> 将角色从用户的角色集合中移除
user.getRoles().remove(r1);
user.getRoles().remove(r2);