一. 表與表之間的關(guān)系
1. 一對多的關(guān)系: 一對多建表,通過外鍵建立關(guān)系.
2.多對多的關(guān)系: 多對多建表,通過第三張表建立關(guān)系.
二.Hibernate的一對多操作
1.一對多映射配置
以客戶和聯(lián)系人為例: 客戶為一,聯(lián)系人是多;
第一步: 創(chuàng)建兩個實(shí)體類: Customer類即客戶類 和 LinkMan類即聯(lián)系人類,其中Customer類表示一 ,LinkMan類表示多;
第二步: 讓兩個實(shí)體類之間相互表示;
(1)在客戶實(shí)體類里面表示多個聯(lián)系人
//在客戶實(shí)體類里面表示多個聯(lián)系人,一個客戶有多個聯(lián)系人
//hibernate要求使用集合表示多的數(shù)據(jù),使用set集合
private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();
public Set<LinkMan> getSetLinkMan() {
return setLinkMan;
}
public void setSetLinkMan(Set<LinkMan> setLinkMan) {
this.setLinkMan = setLinkMan;
}
(2)在聯(lián)系人類里面表示所屬客戶
// 在聯(lián)系人實(shí)體類里面表示所屬客戶,一個聯(lián)系人只能屬于一個客戶
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
第三步: 配置映射關(guān)系
(1) 一般一個實(shí)體類對應(yīng)一個映射文件
(2) 在映射文件中,配置一對多關(guān)系
Customer類的配置文件的內(nèi)容
<hibernate-mapping>
<!-- 配置類和表對應(yīng)
class標(biāo)簽
name屬性: 實(shí)體類的全路徑
table屬性: 數(shù)據(jù)表的名稱 -->
<class name="com.company.Customer" table="customer">
<id name="cid" column="cid">
<!--設(shè)置數(shù)據(jù)表id增長策略-->
<generator class="native"></generator>
</id>
<property name="custName" column="custName"></property>
<property name="custLevel" column="custLevel"></property>
<property name="custSource" column="custSource"></property>
<property name="custPhone" column="custPhone"></property>
<property name="custMobile" column="custMobile"></property>
<!-- 在客戶映射文件中,表示所有聯(lián)系人
使用set標(biāo)簽表示所有聯(lián)系人
set標(biāo)簽里面有name屬性:Set集合的對象
inverse 屬性: 取消一對外鍵的操作 -->
<set name="setLinkMan" cascade="save-update,delete" inverse="true">
<!-- 一對多建表,有外鍵
hibernate機(jī)制: 雙向維護(hù)外鍵,在一和多那一方都配置外鍵
column屬性值: 外鍵名稱 -->
<key column="cid"></key>
<!--客戶所有人的聯(lián)系人,class里面寫聯(lián)系人實(shí)體類全路徑-->
<one-to-many class="com.company.LinkMan"></one-to-many>
</set>
</class>
</hibernate-mapping>
2.一對多級聯(lián)保存
public void TestGave1() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到SessionFactory對象
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//開啟事務(wù)
tx = session.beginTransaction();
//添加一個客戶,為這個客戶添加一個聯(lián)系人
//1.創(chuàng)建客戶和聯(lián)系人對象
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("普通客戶");
customer.setCustSource("網(wǎng)絡(luò)");
customer.setCustPhone("110");
customer.setCustMobile("999");
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("小宏");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("911");
//2.把聯(lián)系人放到客戶里面
<!-- 簡便方法:
1. 在Customer配置文件中的set標(biāo)簽中添加cascade屬性,值為: save-update
這樣配置之后,就可以省略linkMan 的 setCustomer方法 和 session.save(linkMan) 方法
-->
customer.getSetLinkMan().add(linkMan);
// linkMan.setCustomer(customer);
//3.保存客戶
session.save(customer);
//session.save(linkMan);
//提交事務(wù)
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
3.一對多的級聯(lián)刪除
public void TestDelete() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到SessionFactory對象
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//開啟事務(wù)
tx = session.beginTransaction();
//添加一個客戶,為這個客戶添加一個聯(lián)系人
//1.根據(jù)id查詢到客戶對象
Customer customer = session.get(Customer.class, 3);
//2.調(diào)用方法刪除
session.delete(customer);
//提交事務(wù)
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
4.一對多級聯(lián)修改
public void TestUpdate() {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
//得到SessionFactory對象
sessionFactory = HibernateUtils.getSessionFactory();
//得到session
session = sessionFactory.openSession();
//開啟事務(wù)
tx = session.beginTransaction();
//1. 根據(jù)id查詢百度的客戶
Customer baidu = session.get(Customer.class,1);
//2.根據(jù)id查詢聯(lián)系人
LinkMan linkMan = session.get(LinkMan.class,2);
//設(shè)置持久態(tài)的值
baidu.getSetLinkMan().add(linkMan);
//把客戶放到聯(lián)系人里面
linkMan.setCustomer(baidu);
//提交事務(wù)
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
注: inverse屬性
1.因?yàn)閔ibernate是雙向維護(hù),在客戶和聯(lián)系人里面都需要維護(hù)外鍵,修改客戶的時候修改一次外鍵,造成效率問題
2.解決方案: 在Customer配置文件中的set標(biāo)簽中添加inverse屬性,屬性值: true