一對多、多對一
在表中表達:外鍵

在對象中的表達:集合(使用Set集合)

在orm元數據文件中配置:
在上述實體中添加了相應的集合(Set<LinkMan>)跟對象(Customer)屬性后,就得在orm元數據中去配置這兩個屬性了
在一的一方配置(即擁有集合的一方)
在Customer.hbm.xml中寫入
<!--
name: 填寫集合屬性名
column: 外鍵名(數據庫表中的外鍵名)
class: 與我關聯的類的名稱,即多的一方的實體類名
-->
<set name="linkman">
<!-- 要指定的外鍵列名 -->
<key column="lkm_cust_id"></key>
<!-- 指定對應的關系:一對多 -->
<one-to-many class="LinkMan" />
</set>
在多的一方配置
在LinkMan.hbm.xml中寫入
<!--
name: 屬性名
column: 外鍵列名
class: 與我關聯的類的名稱,即一的一方的實體類的名稱
-->
<many-to-one name="customer" column="lkm_cust_id" class="Customer">
</many_to_one>
一對多關系操作
創建客戶跟聯系人,並指定客戶對應的聯系人
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 創建客戶跟聯系人
Customer customer = new Customer();
customer.setCust_name("Sacrtlett");
// 創建客戶
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("Eric Jin");
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("taylor");
// 添加關系
customer.getLinkMens().add(linkMan);
customer.getLinkMens().add(linkMan1);
linkMan.setCustomer(customer);
linkMan1.setCustomer(customer);
// 保存
session.save(customer);
session.save(linkMan);
session.save(linkMan1);
// -------------------------------------
// 提交事務
tx.commit();
}
為客戶添加聯系人
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 獲取要操作的客戶
Customer c = session.get(Customer.class, 1L);
// 創建聯系人
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("mike");
// 將聯系人添加到客戶,將客戶設置到聯系人中
c.getLinkMens().add(linkMan);
linkMan.setCustomer(c);
// 保存
session.save(linkMan);
// -------------------------------------
// 提交事務
tx.commit();
}
解除客戶與聯系人的關系
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 獲取要操作的客戶
Customer c = session.get(Customer.class, 1L);
// 獲取要移除的聯系人
LinkMan lm = session.get(LinkMan.class, 1L);
// 將聯系人從客戶集合集合中刪除
c.getLinkMens().remove(lm);
lm.setCustomer(null);
// -------------------------------------
// 提交事務
tx.commit();
}
多對多
在表中表達

上面的圖片中,通過第三方的一張表將Author表跟Book表聯系了起來,而這第三方表最少應該有兩列,一列是與Author表的id關聯的外鍵,一列是與Book表關聯的外鍵。
在上圖中,第三張表的Author_id的跟Book_id中1對應了1,1還對應了2,這表示大灰狼參與編寫了java編程跟python精通這兩本書。而3也與1對應了,這表示參與了編寫java精通的還有大老虎,
一個作者可以編寫多本書,而一本書也可以由多個作者編寫,這很好的體現了多對多的思想
在對象中表達

在orm元數據文件中配置:
由於都是多的一方,所以兩方的配置應該是一模一樣的,只是需要把相應的參數修改一下就可以了
在Author.hbm.xml中寫入
<!--
name: 實體勒種集合的屬性名
tables: 配置第三張表的表名
key下面的column: 外鍵名,第三張表與我關聯的外鍵名
class: 與我關聯的類名,即另外一方的實體類的類名
many-to-many: 我引用別人的外鍵,即第三張表與另外一方關聯的外鍵名
-->
<set name="book" tables="sys_author_book">
<!-- 要指定的外鍵名 -->
<key column="author_id"></key>
<!-- 指定對應關系 -->
<many-to-many class="Book" column="book_id" />
</set>
在Book.hbm.xml中寫入
由於都是多的一方,所以只需要把相應的參數做一下修改即可
<set name="author" tables="sys_author_book">
<!-- 要指定的外鍵名 -->
<key column="book_id"></key>
<!-- 指定對應關系 -->
<many-to-many class="Author" column="author_id" />
</set>
多對多關系操作
添加關聯
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 創建兩個Author
Author a1 = new Author();
a1.setAuthor_name("大灰狼");
Author a2 = new Author();
a2.setAuthor_name("大熊貓");
// 創建兩個Book
Book b1 = new Book();
b1.setBook_name("java編程");
Book b2 = new Book();
b2.setBook_name("python精通");
// 作者關系表達
a1.getBook().add(b1);
a1.getBook().add(b2);
a2.getBook().add(b1);
// 書籍關系表達
/*
在這里應該注意,在上面a1跟a2已經對第三方表進行了維護,已經往第三張表里面
插入數據了,如果b1跟b2再去維護,在往是第三張表里面插入數據就會出錯,所以
不需要再讓書籍去維護,硬是要維護也行,只需要去書籍的orm配置文件中將inverse
配置成true放棄維護就可以了
*/
// 保存
session.save(a1);
session.save(a2);
session.save(b1);
session.save(b2);
// -------------------------------------
// 提交事務
tx.commit();
}
結論:將來在開發中,如果遇到多對多關系,一定要選擇一方放棄維護選擇放棄誰要根據業務需求來定,比如要給作者指定書籍,那么就給作者維護。如果要為書籍配備作者,就是指定書籍維護
為作者添加書籍
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 獲取Author
Author a = session.get(Author.class, 1L);
// 創建書籍
Book b = new Book();
b.setBook_name("c語言入門");
// 將書籍與作者關聯
a.getBook().add(b);
// 保存
session.save(b);
// -------------------------------------
// 提交事務
tx.commit();
}
解除某個作者的一本書籍
public void test(){
// 獲取session
Session session = HBUtils.CurrentSession();
// 獲取事務並開啟
Transaction tx = session.beginTransaction();
// -------------------------------------
// 獲取Author
Author a = session.get(Author.class, 1L);
// 獲取書籍
Book b = session.get(Book.class, 1L);
// 將書籍從角色中移除
a.getBook().remove(b);
// -------------------------------------
// 提交事務
tx.commit();
}
配置級聯跟是否維護
級聯操作:cascade
有的時候覺得像 ssession.save(b) session.save(a) 既要將Author的對象持久化又要將Book對象持久化太麻煩了,於是想在持久化作者的時候順便把書籍也持久化,這時就可以使用cascade級聯操作
級聯參數
save-update: 級聯保存更新
delete: 級聯刪除
all: 相當於 save-update + delete
一對多中使用級聯
在主表設置:
<set name="linkMens" cascade="save-update">
<!-- 要指定的外鍵列名 -->
<key column="lkm_cust_id"></key>
<!-- 指定對應關系 -->
<one-to-many clss="linkMan" />
</set>
也可以在從表設置:
<many-to-one name="customer" column="lkm_cust_id" class="Customer" cascade="all"></many-to-one>
在設置之后就可以在session.save(a)的時候也session.save(b)了
注意: 一般不建議設置cascade的屬性為delete,太危險!
多對多中使用級聯
<set name="author" tables="sys_author_book" cascade="all">
<!-- 要指定的外鍵名 -->
<key column="book_id"></key>
<!-- 指定對應關系 -->
<many-to-many class="Author" column="author_id" />
</set>
注意:在多對多中一般不建議使用級聯
配置關系是否維護
在操作一對多或者多對多的時候,兩方都會對外鍵進行維護,這顯得很多余,降低效率,甚至在多對多中都去維護還會報錯!只需要由一方維護就可以了,這時可以通過設置inverse來讓一方放棄維護而全權交由對方去維護
inverse屬性:
true:當前配置的對象不維護關系,全權交由另一方維護
false(默認):當前配置的對象自己維護關系
一對多
<!-- 設置用戶對象不維護,交由聯系人對象維護 -->
<set name="linkMens" inverse="true">
<!-- 要指定的外鍵列名 -->
<key column="lkm_cust_id"></key>
<!-- 指定對應關系 -->
<one-to-many clss="linkMan" />
</set>
當設置了不再維護后,那么客戶維護聯系人的代碼可以省略
// c.getLinkMans().add(lm1);
// c.getLinkMans().add(lm2);
注意:只能是一的一方放棄維護,多的一方含有外鍵,不能自己放棄自己
如果放棄了維護,那么在一的一方在刪除數據時,由於沒有維護,會不允許刪除,因為已經被聯系人關聯了,這時必須使一的一方也維護
多對多
多對多不管哪一方都能放棄維護,至於具體是哪一方放棄維護,要根據項目的實際情況來定
<!-- Book放棄維護,交給Author去維護 -->
<set name="author" tables="sys_author_book" inverse="true">
<!-- 要指定的外鍵名 -->
<key column="book_id"></key>
<!-- 指定對應關系 -->
<many-to-many class="Author" column="author_id" />
</set>
