一. 表與表之間的關系
1. 一對多的關系: 一對多建表,通過外鍵建立關系.
2.多對多的關系: 多對多建表,通過第三張表建立關系.
二.Hibernate的一對多操作
1.一對多映射配置
以客戶和聯(lián)系人為例: 客戶為一,聯(lián)系人是多;
第一步: 創(chuàng)建兩個實體類: Customer類即客戶類 和 LinkMan類即聯(lián)系人類,其中Customer類表示一 ,LinkMan類表示多;
第二步: 讓兩個實體類之間相互表示;
(1)在客戶實體類里面表示多個聯(lián)系人
//在客戶實體類里面表示多個聯(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)系人實體類里面表示所屬客戶,一個聯(lián)系人只能屬于一個客戶
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
第三步: 配置映射關系
(1) 一般一個實體類對應一個映射文件
(2) 在映射文件中,配置一對多關系
Customer類的配置文件的內(nèi)容
<hibernate-mapping>
<!-- 配置類和表對應
class標簽
name屬性: 實體類的全路徑
table屬性: 數(shù)據(jù)表的名稱 -->
<class name="com.company.Customer" table="customer">
<id name="cid" column="cid">
<!--設置數(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標簽表示所有聯(lián)系人
set標簽里面有name屬性:Set集合的對象
inverse 屬性: 取消一對外鍵的操作 -->
<set name="setLinkMan" cascade="save-update,delete" inverse="true">
<!-- 一對多建表,有外鍵
hibernate機制: 雙向維護外鍵,在一和多那一方都配置外鍵
column屬性值: 外鍵名稱 -->
<key column="cid"></key>
<!--客戶所有人的聯(lián)系人,class里面寫聯(lián)系人實體類全路徑-->
<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();
//開啟事務
tx = session.beginTransaction();
//添加一個客戶,為這個客戶添加一個聯(lián)系人
//1.創(chuàng)建客戶和聯(lián)系人對象
Customer customer = new Customer();
customer.setCustName("百度");
customer.setCustLevel("普通客戶");
customer.setCustSource("網(wǎng)絡");
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標簽中添加cascade屬性,值為: save-update
這樣配置之后,就可以省略linkMan 的 setCustomer方法 和 session.save(linkMan) 方法
-->
customer.getSetLinkMan().add(linkMan);
// linkMan.setCustomer(customer);
//3.保存客戶
session.save(customer);
//session.save(linkMan);
//提交事務
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();
//開啟事務
tx = session.beginTransaction();
//添加一個客戶,為這個客戶添加一個聯(lián)系人
//1.根據(jù)id查詢到客戶對象
Customer customer = session.get(Customer.class, 3);
//2.調(diào)用方法刪除
session.delete(customer);
//提交事務
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();
//開啟事務
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);
//設置持久態(tài)的值
baidu.getSetLinkMan().add(linkMan);
//把客戶放到聯(lián)系人里面
linkMan.setCustomer(baidu);
//提交事務
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
sessionFactory.close();
}
}
注: inverse屬性
1.因為hibernate是雙向維護,在客戶和聯(lián)系人里面都需要維護外鍵,修改客戶的時候修改一次外鍵,造成效率問題
2.解決方案: 在Customer配置文件中的set標簽中添加inverse屬性,屬性值: true