《Hibernate學習筆記九》:多對一和一對多的關聯關系
前面介紹了一對一的關聯關系在Hibernate應該如何來實作,這篇博文就來介紹下多對一和一對多的關聯關系。
多對一和一對多的關聯關系在我們的生活中也比較常見,例如,在我們學生時代,一個班級可以有多個學生,而一個學生隻能屬于一個班級,這就是一個多對一(一對多)的例子;
還有在我們的工作中,一個工作小組可以有多個使用者,而一個使用者隻能屬于一個小組,這也是一個多對一(一對多)的關系的例子。
1、多對一的單向關聯關系
下面就以一個工作小組可以有多個使用者,而一個使用者隻能屬于一個小組,這個例子來進行設計介紹如何建立一個多對一的關聯關系。
在類的層面上:在多的一方加另一個的引用
在資料庫層面上:在”多對一”中”多”的一方設定外鍵即可
1.1、多對一單向的關聯關系的Annotation實作
Group類
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
User類
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
private Group group;//指定外鍵
@ManyToOne //多對一 即一個組有多個使用者,而一個使用者隻能屬于一個組
@JoinColumn(name="group_id")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
由于User實體和Group實體,User是處于“多對一”中“多”的一方,是以,我們就在User類中設定一個Group的外鍵即可建立多對一的關聯關系。
測試結果如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIH5EUuEjdfVmbvJTeuFWbfVGdh5mclJWaI9CXt92Yu4GZkV3bsNmLix2ZuAjeuETbvNmL0pnbrh3Nvw1LcpDc0RHaiojIsJye.png)
1.2、多對一單向的關聯關系的XXX.hbm.xml實作
Group類和User類
Group和User類中,有相應的屬性和get、set方法即可。
且User類中有一個Group的引用。
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 package="com.hibernate.model">
<class name="Group" table="t_group" >
<id name="idGroup" column="idGroup">
<generator class="native"/>
</id>
<property name="nameGroup" column="nameGroup"/>
</class>
</hibernate-mapping>
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.hibernate.model">
<class name="User" table="t_user" >
<id name="idUser" column="id">
<generator class="native"/>
</id>
<property name="nameUser" column="nameUser"/>
<!-- 這樣就構成了一個多對一的關系 -->
<many-to-one name="group" column="groupId"></many-to-one>
</class>
</hibernate-mapping>
通過在User.hbm.xml檔案中,加入
<many-to-one name="group" column="groupId"></many-to-one>
就建構了多對一的關聯關系。
2、一對多的單向關聯關系
在類實體的層面上:在一的一方存在多方的集合
在資料庫的層面上:在多方加外鍵
下面就以一個工作小組可以有多個使用者,而一個使用者隻能屬于一個小組,這個例子來進行設計介紹如何建立一個一對多的關聯關系。
2.1、一對多單向的關聯關系的Annotation實作
先看多的這方:User類
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
再看一的這方:Group類
由于是一對多的關系,是以在一的這方必須要有一個容器,這裡采用的Set,Set容器可以用來避免重複,資料庫中也是不允許主鍵重複的,與我們資料庫的邏輯是符合的。
然後在Set容器的get方法上采用@OneToMany注解來進行修飾。并通過@JoinColumn(name=”groupId”)來指定外鍵名(外鍵在多的一方的表中生成)。
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
@OneToMany //一對多關系的指定
@JoinColumn(name="groupId")
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
測試結果如下:
如果我們不通過@JoinColumn(name=”groupId”)來指定外鍵名(外鍵在多的一方的表中生成),則Hibernate會為我們生成一個中間表,即将一對多當成多對多來進行處理了。
測試結果如下:
2.2、一對多單向的關聯關系的XXX.hbm.xml實作
Group類
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
在Group.bhm.xml檔案:
主要是為Group類中的Set屬性,添加如下的代碼即可構成一對多的關聯關系:
<set name="set" >
<key column="groupId"></key>
<one-to-many class="com.hibernate.model.User"/>
</set>
完整内容如下:
<?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.hibernate.model">
<class name="Group" table="t_group" >
<id name="idGroup" column="idGroup">
<generator class="native"/>
</id>
<property name="nameGroup" column="nameGroup"/>
<set name="set" >
<key column="groupId"></key>
<one-to-many class="com.hibernate.model.User"/>
</set>
</class>
</hibernate-mapping>
User類
public class User {
private int idUser;
private String nameUser;
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
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.hibernate.model">
<class name="User" table="t_user" >
<id name="idUser" column="id">
<generator class="native"/>
</id>
<property name="nameUser" column="nameUser"/>
</class>
</hibernate-mapping>
一對多(多對一)雙向關聯
在我們了解了一對多和多對一的單向關聯之後,雙向關聯就相當簡單了,就是将這兩者的單向關聯進行合并即可。下面隻介紹下使用Annotation來建構雙向關聯。
在一的一方:Group實體類
類似建構一對多。
隻是有一點需要注意:指定mappedBy
代碼如下:
@Entity
@Table(name="t_group") //指定表名
public class Group {
private int idGroup;
private String nameGroup;
private Set<User> set=new HashSet<User>();
@OneToMany(mappedBy="group") //一對多關系的指定 且由于是雙向關聯,必須指定mappedBy,否則會生成兩個外鍵。
public Set<User> getSet() {
return set;
}
public void setSet(Set<User> set) {
this.set = set;
}
@Id
@GeneratedValue
public int getIdGroup() {
return idGroup;
}
public void setIdGroup(int idGroup) {
this.idGroup = idGroup;
}
public String getNameGroup() {
return nameGroup;
}
public void setNameGroup(String nameGroup) {
this.nameGroup = nameGroup;
}
}
在多的一方的User類
類似建構多對一的關聯即可。
@Entity
@Table(name="t_user") //指定表名
public class User {
private int idUser;
private String nameUser;
private Group group;
@ManyToOne
@JoinColumn(name="groupId")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getIdUser() {
return idUser;
}
public void setIdUser(int idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
}
這樣就Ok了。
小結
多對一和一對多的單向關聯關系的Annotation和XXX.hbm.xml檔案的實作均比較簡單。