-----------------一對多,多對一
- 級聯(lián)在兩方中都可以,但是只能同時有一家配置
- 多對一重點是雙方關(guān)系互相保存,如果在一和多的實體對象相互關(guān)聯(lián)之后想要只保存一的部分使多的部分自動保存則需要配置級聯(lián) cascade字段
-------------原始相互關(guān)聯(lián),相互保存
--------------------------保存客戶及其聯(lián)系人
Customer c = new Customer();
c.setCust_name("aaa");
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("bbb");
LinkMan lm2 = new LinkMan();
lm2.setLkm_name("ccc");
//表達一對多,客戶下有多個聯(lián)系人
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2);
//表達對對對,聯(lián)系人屬于哪個客戶
lm1.setCustomer(c);
lm2.setCustomer(c);
session.save(c);
session.save(lm1);
session.save(lm2);
//-------------------------------------------------獲得客戶添加聯(lián)系人
Customer c = session.get(Customer.class,1l);
//2> 創(chuàng)建聯(lián)系人
LinkMan lm1 = new LinkMan();
lm1.setLkm_name("ddd");
//3> 將聯(lián)系人添加到客戶,將客戶設(shè)置到聯(lián)系人中
c.getLinkMens().add(lm1);
lm1.setCustomer(c);
//4> 執(zhí)行保存
session.save(lm1);
------------------------------刪除客戶及其聯(lián)系人
Customer c = session.get(Customer.class,1l);
//2> 獲得要移除的聯(lián)系人
LinkMan lm = session.get(LinkMan.class, 3l);
//3> 將聯(lián)系人從客戶集合中移除
c.getLinkMens().remove(lm);
lm.setCustomer(null);
--------------------原始的需要保存兩次,晉級的在元配置文件中一的部分加入cascade字段則只需要保存一的部分省略保存多的部分-----級聯(lián)
----------- 省略保存聯(lián)系人(多)的部分cascade:save-update
session.save(c);
// session.save(lm1);
// session.save(lm2);
----------------級聯(lián)刪除客戶下的聯(lián)系人cascade:delete
Customer c = session.get(Customer.class,1l);
//2>調(diào)用delete刪除客戶
session.delete(c);
---------
- 元配置和主配置文件是對應(yīng)的,多加一個元配置主配置文件就要多一條
<mapping resource="cn/itcast/domain/Customer.hbm.xml" />
<mapping resource="cn/itcast/domain/LinkMan.hbm.xml" />
- 元配置文件中一定保證多對一,一對多的column是一樣的
- 表中表達是在多中引入外鍵表達屬于哪個一
- 實體中表達是在一中引入set(map多一個外鍵,list可重復(fù)不選)包含多,在多的實體一方引入一的實體對象以作關(guān)聯(lián)
- char-Charset;varchar-String
//表達多對一關(guān)系
private Customer customer ;
---------------------------------------------
//使用set集合,表達一對多關(guān)系(初始化)
private Set<LinkMan> linkMens = new HashSet<LinkMan>();
----------------------------------元素實體中一的一方是多一個set,配置文件需要多,注意class如果page沒配置需要寫全類名而不能簡化
<!-- 集合,一對多關(guān)系,在配置文件中配置 -->
<!--
name屬性:集合屬性名
column屬性: 外鍵列名
class屬性: 與我關(guān)聯(lián)的對象完整類名 -->
<!--
級聯(lián)操作: cascade
save-update: 級聯(lián)保存更新
delete:級聯(lián)刪除
all:save-update+delete
級聯(lián)操作: 簡化操作.目的就是為了少些兩行代碼. -->
<!-- inverse屬性: 配置關(guān)系是否維護.
true: customer不維護關(guān)系
false(默認值): customer維護關(guān)系
inverse屬性: 性能優(yōu)化.提高關(guān)系維護的性能.
原則: 無論怎么放棄,總有一方必須要維護關(guān)系.
一對多關(guān)系中: 一的一方放棄.也只能一的一方放棄.多的一方不能放棄.
-->
<set name="linkMens" inverse="true" cascade="delete" >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>
-----------------------------------多對一配置引入的對象
<!-- 多對一 -->
<!--
name屬性:引用屬性名
column屬性: 外鍵列名
class屬性: 與我關(guān)聯(lián)的對象完整類名
-->
<!--
級聯(lián)操作: cascade
save-update: 級聯(lián)保存更新
delete:級聯(lián)刪除
all:save-update+delete
級聯(lián)操作: 簡化操作.目的就是為了少些兩行代碼.
-->
<!-- 多的一方: 不能放棄維護關(guān)系的.外鍵字段就在多的一方. -->
<many-to-one name="customer" column="lkm_cust_id" class="Customer" >
</many-to-one>
-----------------多對多
- 代碼中保存和配置文件是互相搭配使用,僅設(shè)置一方會出現(xiàn)錯誤
--------------user.hbm.xml
<!-- 多對多關(guān)系表達 -->
<!--
name: 集合屬性名
table: 配置中間表名
key
|-column:外鍵,別人引用"我"的外鍵列名
class: 我與哪個類是多對多關(guān)系
column:外鍵.我引用比人的外鍵列名
-->
<!-- cascade級聯(lián)操作:
save-update: 級聯(lián)保存更新
delete:級聯(lián)刪除
all:級聯(lián)保存更新+級聯(lián)刪除
結(jié)論: 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: 放棄維護外鍵關(guān)系
false(默認值):維護關(guān)系
結(jié)論: 如果遇到多對多關(guān)系.一定要選擇一方放棄維護關(guān)系.
一般誰來放棄要看業(yè)務(wù)方向(由不確定一方進行維護). 例如錄入員工時,需要為員工指定所屬角色.
那么業(yè)務(wù)方向就是由員工維護角色. 角色不需要維護與員工關(guān)系.角色放棄維護
-->
<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>
-------------每增加一條元配置文件需要在主配置文件中添加關(guān)聯(lián)
<mapping resource="cn/fb/domain/Role.hbm.xml" />
--------------------text實體之間相互關(guān)聯(lián)僅保存一方(都保存也可),保存只保存不確定一方(但在配置中有cascade屬性代替)并且需要放棄維護一方因為都維護會在第三張關(guān)系表中插入相同數(shù)據(jù)(一對多不會出現(xiàn)類似是因為插入的字段可以重復(fù)修改)
// 多對多添加
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> 創(chuàng)建公關(guān)角色
Role r = new Role();
r.setRole_name("男公關(guān)");
//3> 將角色添加到用戶中
user.getRoles().add(r);
//4> 將角色轉(zhuǎn)換為持久化
//session.save(r);
---------------刪除用戶一個角色,同樣需要獲得角色實體對象,然后在相應(yīng)集合刪除
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);