Hibernate的關聯映射

首先咱們瞭解一個名詞ORM,全稱是(Object Relational Mapping),即對象關係映射。ORM的實現思想就是將關係型數據庫中表的數據映射成對象,以對象的形式展示,這樣開發人員就能夠把對數據庫的操做轉化爲對這些對象的操做。Hibernate正是實現了這種思想,達到了方便開發人員以面向對象的思想來實現對數據庫的操做。java

Hibernate在實現ORM功能的時候主要用到的文件有:映射類(*.java)、映射文件(*.hbm.xml)和數據庫配置文件(*.properties/*.cfg.xml),它們各自的做用以下:git

  • 映射類(*.java):它是描述數據庫表的結構,表中的字段在類中被描述成屬性,未來就能夠實現把表中的記錄映射成爲該類的對象了。
  • 映射文件(*.hbm.xml):它是指定數據庫表和映射類之間的關係,包括映射類和數據庫表的對應關係、表字段和類屬性的對應關係。
  • 數據庫配置文件(*.properties/*.cfg.xml):它是指定與數據庫鏈接時須要的鏈接信息,好比鏈接哪一種數據庫、登陸數據庫的用戶名、密碼以及鏈接字符串等。固然還能夠把映射類的地址映射信息放在這裏。

接下來讓咱們一塊兒走進Hibernate的幾種關聯映射關係:

單向一對一關聯映射(one-to-one):

兩個對象之間一對的關係,例如:Person(人)- IdCard(身份證)github

有兩種策略能夠實現一對一的關聯映射:數據庫

  • 主鍵關聯:即讓兩個對象具備相同的主鍵值,以代表它們之間的一一對應的關係;數據庫表不會有額外的字段來維護它們之間的關係,僅經過表的主鍵來關聯。以下圖:

注意:須要在Person.hbm.xml映射文件中配置one-to-one標籤,以下:app

<?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.nnngu.Person" table="t_person">  
        <id name="id">  
            <!-- 採用foreign生成策略,foreign會取得關聯對象的標識 -->  
            <generator class="foreign">  
                <!-- property只關聯對象 -->  
                <param name="property">idCard</param>  
            </generator>  
        </id>  
        <property name="name"/>  
        <!-- one-to-one指示hibernate如何加載其關聯對象,默認根據主鍵加載  
            也就是拿到關係字段值,根據對端的主鍵來加載關聯對象  
         -->  
        <one-to-one name="idCard" constrained="true"/>  
    </class>  
</hibernate-mapping>
  • 惟一外鍵關聯:外鍵關聯,原本是用於多對一的配置,可是加上惟一的限制以後(採用<many-to-one>標籤來映射,指定多的一端unique爲true,這樣就限制了多的一端的多重性爲一),也能夠用來表示一對一關聯關係,其實它就是多對一的特殊狀況。以下圖:

須要在Person.hbm.xml映射文件中配置many-to-one標籤,並指定unique爲true,以下:post

<?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.nnngu.Person" table="t_person">  
        <id name="id">  
            <generator class="native">  
                <!-- property只關聯對象 -->  
                <param name="property">idCard</param>  
            </generator>  
        </id>  
        <property name="name"/>  
        <many-to-one name="idCard" unique="true"/>  
    </class>  
</hibernate-mapping>

注意:由於一對一的主鍵關聯映射擴展性很差,當咱們的須要發生改變想要將其變爲一對多的時候變沒法操做了,因此咱們遇到一對一關聯的時候常常會採用惟一外鍵關聯來解決問題,而不多使用一對一主鍵關聯。.net

單向多對一關聯映射(many-to-one):

多對一關聯映射原理:在多的一端加入一個外鍵,指向一的一端,以下圖:hibernate

關鍵映射代碼——在多的一端加入以下標籤映射:code

<many-to-one name="group" column="groupid"/>

單向一對多關聯映射(one-to-many):

一對多關聯映射和多對一關聯映射原理是一致的,都是在多的一端加入一個外鍵,指向一的一端。以下圖(學生和班級):xml

注意:它與多對一的區別是維護的關係不一樣

  • 多對一維護的關係是:多指向一的關係,有了此關係,加載多的時候能夠將一加載上來。
  • 一對多維護的關係是:一指向多的關係,有了此關係,在加載一的時候能夠將多加載上來。

關鍵映射代碼——在一的一端加入以下標籤映射:

<set name="students">  
      <key column="classesid"/>  
      <one-to-many class="com.nnngu.Student"/>  
</set>

單向多對多映射(many-to-many):

多對多關聯映射須要新增長一張表才完成基本映射,以下圖:

關鍵映射代碼——能夠在User的一端加入以下標籤映射:

<set name="roles" table="t_user_role">  
     <key column="user_id"/>  
     <many-to-many class="com.nnngu.Role" column="role_id"/>  
</set>

雙向一對一關聯映射:

對比單向一對一映射,須要在IdCard也加入<one-to-one>標籤。示意圖以下:

雙向一對一主鍵映射關鍵映射代碼——在IdCard端新加入以下標籤映射:

<one-to-one name="person"/>

雙向一對一惟一外鍵映射關鍵映射代碼——在IdCard端新加入以下標籤映射:

<one-to-one name="person"property-ref="idCard"/>

注意:一對一惟一外鍵關聯雙向採用<one-to-one>標籤映射,必須指定<one-to-one>標籤中的property-ref屬性爲關係字段的名稱

雙向一對多關聯映射(很是重要):

採用雙向一對多關聯映射的目的主要是爲了解決單向一對多關聯的缺陷。

雙向一對多關聯的映射方式:

  • 在一的一端的集合上採用<key>標籤,在多的一端加入一個外鍵
  • 在多的一端採用<many-to-one>標籤

注意:<key>標籤和<many-to-one>標籤加入的字段要保持一致,不然會產生數據混亂。

在Classes的一端加入以下標籤映射:

<set name="students"inverse="true">  
      <key column="classesid"/>  
      <one-to-many class="com.nnngu.Student"/>  
</set>

在Student的一端加入以下標籤映射:

<many-to-one name="classes" column="classesid"/>

瞭解inverse屬性:

  • inverse屬性能夠用在一對多和多對多雙向關聯上,inverse屬性默認爲false,爲false表示本端能夠維護關係,若是inverse爲true,則本端不能維護關係,會交給另外一端維護關係,本端失效。因此一對多關聯映射咱們一般在多的一端維護關係,讓一的一端失效。
  • inverse是控制方向上的反轉,隻影響存儲。

雙向多對多關聯映射:

雙向的目的就是爲了兩端都能將對方加載上來,和單向多對多的區別就是雙向須要在兩端都加入標籤映射,須要注意的是:

  • 生成的中間表名稱必須同樣
  • 生成的中間表中的字段必須同樣

Role(角色)端關鍵映射代碼:

<set name="users" table="t_user_role">  
       <key column="role_id"/>  
       <many-to-many class="com.nnngu.User" column="user_id"/>  
</set>

User(用戶)端關鍵映射代碼:

<set name="roles" table="t_user_role">  
      <key column="user_id"/>  
      <many-to-many class="com. nnngu.Role" column="role_id"/>  
</set>

總結

對於上面的七種關聯映射,最重要的就是一對多的映射,由於它更貼近咱們的現實生活,好比:教室和學生就能夠是典型的一對多的關係,而咱們開發軟件的目的之一就是爲了解決一些生活中重複性問題,把那些重複的問題交給計算機來幫助咱們完成,從而提升咱們的工做效率。


本文永久更新地址:https://github.com/nnngu/LearningNotes/blob/master/_posts/2018-03-23-Hibernate%E7%9A%84%E5%85%B3%E8%81%94%E6%98%A0%E5%B0%84.md

相關文章
相關標籤/搜索