Hibernate關聯映射

關係:事物之間相互做用、相互聯繫的狀態。範圍最大。java

聯繫:在關係數據庫中表示實體與實體之間的聯繫,1:1,1:n,m:n。sql

關聯:表示對象之間的關係,既有數量性,又有方向性;動詞:將對象之間經過某種方式聯繫起來。數據庫

映射:這裏指java對象和數據庫表的一種對應關係。動詞:造成這種對應關係。spa

級聯:有關係的雙方中操做一方,另外一方也將採起一些動做。hibernate

關聯的聯繫種類code

在不考慮關聯的方向前提下,聯繫就是關係數據庫中表示實體與實體之間的聯繫,1:1,1:n,m:n。xml

一對一聯繫(1:1):如用戶和身份證、一夫一妻對象

一對多聯繫(1:n):如班級和學生blog

多對多聯繫(m:n):如學生和選課開發

關聯的方向:關聯關係的方向可分爲單向關聯和雙向關聯。

雙向關聯的方向其實就不重要了,由於經過任一一方均可以維護彼此的關係。也就是說:在雙向關聯中一對多和多對一都是同樣的。

單向關聯

在關聯標記例如<many-to-one>或者<one-to-many>,方向都是從左到右,換句話說是由左邊維護它們的關係,參見下面例子。

假設存在兩張表person表和address表,它們之間的聯繫是n:1;

即一我的的居住地址是惟一的,一個地址卻能夠多我的居住。

若是在應用的業務邏輯中,僅須要每一個person實例可以查詢獲得其對應的Address實例,而Address實例並不須要查詢獲得其對應的person實例。

<class name="Person" table="person">

    <id name="id" >

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        not-null="true"/>

</class>

<class name="Address" >

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

</class>

 

說明:這是一個多對一的單向關聯:由多的一方來維護它們的關係,須要在name="Person"的class元素內加入關聯標記,<many-to-one>。這種關聯很是多。

假設存在兩張表person表和tel表,它們之間的聯繫是1:n;

即一我的的聯繫電話可能有多個,一個電話只能對應一我的。

若是在應用的業務邏輯中,咱們僅僅關心每一個person實例可以查詢到其對應的全部tel實例,而tel實例並不須要查詢獲得其對應的person實例。

<class name="Person">

    <id name="id" column="personId">

        <generator class="native"/>

    </id>

    <set name="tels">

        <key column="personId" not-null="true" />

        <one-to-many class="Tel"/>

    </set>

</class>

<class name="Tel">

    <id name="id" column="telId">

        <generator class="native"/>

    </id>

</class>

 

說明:這是一個一對多的單向關聯:由一的一方來維護他們的關係,須要在name="Person"的class元素內加入關聯標記,<one-to-many>。這種關聯相對要少一些。大部分狀況下咱們都是操做多的一方的實例。

雙向關聯

在兩邊同時配置單向關聯,就構成了雙向管理。實際開發過程當中,不少時候都是須要雙向關聯的,它在解決單向一對多維護關係的過程當中存在的缺陷起了必定的修補做用。

假設存在兩張表person表和address表,它們之間的聯繫是n:1;

即一我的的居住地址是惟一的,一個地址卻能夠多我的居住。

既須要每一個person實例可以查詢獲得其對應的Address實例,Address實例也須要查詢獲得其對應的person實例。

<class name="Person">

    <id name="id" column="personId">

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        not-null="true"/>

</class>

<class name="Address">

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

    <set name="people" inverse="true">

        <key column="addressId"/>

        <one-to-many class="Person"/>

    </set>

</class>

 

說明:這是一個多對一雙向關聯。由雙方維護彼此的關係。須要在name="Person"的class元素內加入關聯標記,<many-to-one>。同時在name="Address"的class元素內加入集合映射<set>,並在其中加入關聯標記:<one-to-many>。

關聯標記

在hbm.xml中,關聯標記<one-to-one>、<many-to-one>、<one-to-many>、<many-to-many>,關聯的方向都是是從左到右。

關聯標記屬性

簡單介紹下面幾個,除了name是必須,其他都是可選的。更多的咱們參考官文檔。

name="對應本類的屬性名"

column="映射到本表的字段名"

class="映射到本表的實體類"

unique="ture|false":(數據庫外鍵字段生成一個惟一約束)

not-null="ture|false"默認false(數據庫外鍵字段是否容許爲空值)

lazy="ture|false"默認proxy(延遲加載)

cascade(級聯)屬性

級聯的意思是指定兩個對象之間的操做聯動關係,對一個對象執行了操做以後,對其指定的級聯對象也須要執行相同的操做

總共能夠取值爲:all、none、save-update、delete

all-表明在全部的狀況下都執行級聯操做

none-在全部狀況下都不執行級聯操做

save-update-在保存和更新的時候執行級聯操做

delete-在刪除的時候執行級聯操做

集合映射標記<set>

<set name="peoples" inverse="true">

    <key column="addressId"/>

    <one-to-many class="Person"/>

</set>

<set name="peoples" inverse="true">name爲持久化對象的集合的屬性名稱。

<key column="classid" > column外鍵的名稱

<one-to-many class=「cn.edu.bzu.hibernate.Student" /> class持久化類

inverse屬性

控制反轉,主要用在一對多,多對對雙向關聯上,inverse能夠設置到<set>集合上, 默認inverse爲false。爲true表示反轉,由對方負責;反之,不反轉,本身負責;若是不設,one和many兩方都要負責控制,所以,會引起重複的sql語句以及重複添加數據。

誰是多誰是一

咱們說一對一,多對一,多對可能是誰對誰呢?在映射文件(.hbm.xml)中class元素中的對象關聯標記中,好比<many-to-one>

那麼class元素的屬性name就是many,<many-to-one>標記中 name就是one。同時column="addressId"指明瞭person表的外鍵。

<class name="Person" table="person">

    <id name="id" >

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        not-null="true"/>

</class>

 

上面例子中Person就是many,address就是one。

能夠這麼理解<many-to-one>在誰裏面,誰就是many,<many-to-one>的屬性name就是one。

單向關聯hbm.xml配置,單向關聯經常使用的是多對一,單向 many-to-one 關聯是最多見的單向關聯關係。這種關聯是數據庫關係模式中的多對一:

這個表的一個外鍵引用目標表的主鍵字段。

下面例子中的person與address聯繫(數據庫用語)爲n:1,能夠這麼理解:

即一我的的居住地址是惟一的,一個地址卻能夠多我的居住。

<class name="Person" table="person">

    <id name="id" >

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        not-null="true"/>

</class>

<class name="Address" >

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

</class>

 

注意:<many-to-one>標籤中column="addressId",爲person表添加一個外鍵addressId。

sql輸出:

create table Person ( personId bigint not null primary key, addressId bigint not null )

create table Address ( addressId bigint not null primary key )

雙向關聯hbm.xml配置

一、一對多/多對一

雙向多對一關聯 是最多見的關聯關係。下面的例子解釋了這種標準的父/子關聯關係。

下面例子中的person與address聯繫(數據庫用語)爲n:1,能夠這麼理解:

即一我的的居住地址是惟一的,一個地址卻能夠多我的居住。

<class name="Person">

    <id name="id" column="personId">

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        not-null="true"/>

</class>

<class name="Address">

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

    <set name="people" inverse="true">

        <key column="addressId"/>

        <one-to-many class="Person"/>

    </set>

</class>

 

注意:many-to-one關聯須要將one的一端加入inverse="true";column="addressId"指明瞭person表的外鍵。

sql輸出:

create table Person ( personId bigint not null primary key, addressId bigint not null )

create table Address ( addressId bigint not null primary key )

二、一對一

基於外鍵關聯的雙向一對一關聯也很常見。

下面例子中person與address的聯繫(數據庫用語)是1:1,能夠這麼理解:

即一我的只能管理一個地方,一個地方只能由一我的管理。

column="addressId"指明瞭person表的外鍵。

<class name="Person">

    <id name="id" column="personId">

        <generator class="native"/>

    </id>

    <many-to-one name="address"

        column="addressId"

        unique="true"

        not-null="true"/>

</class>

<class name="Address">

    <id name="id" column="addressId">

        <generator class="native"/>

    </id>

    <one-to-one name="person"

        property-ref="address"/>

</class>

 

sql輸出:

create table Person ( personId bigint not null primary key, addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

三、使用鏈接表的關聯

使用鏈接表的關聯一般針對多對多。鏈接表會是數據中另外建的一張表,來存儲兩個實體的聯繫。

這張表有三個字段:自己的id,兩個外鍵分別關聯到兩個實體的主鍵。

下面是student與course的聯繫(數據庫用語)是m:n,能夠這麼理解:

一個學生能夠選多門課程,一門課程也有多個學生。

<class name="Student">

    <id name="id" column="studentId">

        <generator class="native"/>

    </id>

    <set name="courses" table="StudentCourse">

        <key column="studentId"/>

        <many-to-many column="courseId"

        class="Course"/>

    </set>

</class>

<class name="Course">

    <id name="id" column="courseId">

        <generator class="native"/>

    </id>

    <set name="students" inverse="true" table="StudentCourse">

        <key column="courseId"/>

        <many-to-many column="studentId"

        class="Student"/>

    </set>

</class>

 

注意:<set>增長了table屬性,所以會另外建表。

sql輸出:

create table Student ( studentId bigint not null primary key )

create table StudentCourse ( studentId bigint not null, courseId bigint not null, primary key

(studentId, courseId) )

create table Course ( courseId bigint not null primary key )

相關文章
相關標籤/搜索