【SSH進階之路】Hibernate基本原理(一) ,小編介紹了Hibernate的基本原理以及它的核心,采用對象化的思維操作關系型資料庫。
【SSH進階之路】Hibernate搭建開發環境+簡單執行個體(二),小編搭建了基本Hibernate的開發環境,并做了一個簡單執行個體,對它的基本原理有了一個理性的認識。
【SSH進階之路】Hibernate基本映射(三),我們介紹了Hibernate的基本映射(即對一個實體進行映射)的相關概念,并給大家實作相關執行個體,比較簡單。
這篇部落格,我們開始介紹基于基本映射的關聯關系映射。
概念
基本映射是對一個實體進行映射,關聯映射就是處理多個實體之間的關系,将關聯關系映射到資料庫中,所謂的關聯關系在對象模型中有一個或多個引用。
分類
關聯關系分為上述七種,但是由于互相之間有各種關系,可以簡化,例如:多對一與一對多映射,隻是側重的角度不對而已。
映射技巧
映射技巧是小編寫映射檔案的過程,總結的經典内容,總共分為四步,咋看不是特别易懂,但是效果很好。下面我們以執行個體看技巧。
(1)寫注釋
格式為:?屬性,表達的是本對象與?的?關系。
解釋:在寫映射檔案之前先寫注釋,将問号的地方填上相應的内容。例如:<!-- group屬性,表達的是本對象(User)與Group的多對一的關系-->
(2)寫映射的架構(拷模版)
多對一 | <many-to-one name=“” class=“” column=“”/> |
一對多 (Set) | <set name=""> <key column=""></key> <one-to-many class=""/> </set> |
多對多 | <set name="" table=""> <many-to-many class="" column=""/> |
(3)填空
填空,就是将映射的架構資訊,填寫完成,完成映射檔案。
• name屬性:屬性名(注釋中的第1問号)
• class屬性:關聯的實體類型(注釋中的第2個問号)
• column屬性:
○ <many-to-one column="..">:一般可以寫成屬性名加Id字尾,如屬性為group,則column值寫成groupId。
○ 一對多中的<key column="..">:從關聯的對方(對方是多對一)映射中把column值拷貝過來。
○ 多對多中的<key column=“..”>:一般可以寫成本對象的名加Id字尾,如本對象名為User,則寫為userId。
○ 多對多中的<many-to-many column=“..”>:一般可以寫為關聯對象的名稱加Id字尾。
(4)完成
将映射檔案添加到hibernate.hbm.xml中,這個相信大家都知道為什麼。
我們後面所有關聯映射的博文都使用此映射技巧來寫映射檔案,明白之後,速度會非常快。
多對一關聯映射
映射原理
多的一端維護關聯關系,在“多”的一端加入一個外鍵,指向“一”的一端。多的一端持有一的一端的引用,即在“多”的一端加外鍵,指向“一”的一端。
執行個體
比如,多個使用者屬于同一組,我們從對象模型和關系模型兩個角度來分析一下這個例子,如下:
從上圖可以看出,對象模型具有方向性,通過使用者(User)可以看到組(Group),但是不能反過來。使用者群組各對應一張資料庫表,聚合關系需要一個外鍵(groupid)來表示,最後生成的表如下所示:
作用:
當我拿到使用者時直接就可以拿到使用者的組,hibernate在通路多的一端時,可以自動的加載關聯對象。對于使用者(User)來說,它的關聯對象是組(group)。
上面都是多對一關聯映射的基本原理,以及相應的執行個體,下面我們看一下代碼:
代碼
User類
public class User {
private int id;
private String name;
private Group group;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
Group類
public class Group {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.liang.hibernate">
<class name="User" table="t_user">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<!-- group屬性,表達的是本對象與Group的多對一的關系-->
<many-to-one name="group" class="Group" column="groupid"></many-to-one>
<!-- 解釋:
多對一關系标簽:
<many-to-one name=“” class=“” column=“”/>
1、第1個問号:group是User類的屬性,對應于name屬性名
2、第2個問号:class表達的是本對象(User)與Group的關系
3、第3個問号:column是屬性名+Id
當我們寫完注釋之後,我們直接拷貝問号的對應關系即可。
-->
</class>
</hibernate-mapping>
Group.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.liang.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
</class>
</hibernate-mapping>
生成的表結構,與上面的分析的關系模型一樣: