映射文件
映射文件的配置
- name: 屬性的名字波闹。這個類的屬性的名字绒瘦,而且是與之關(guān)聯(lián)的屬性的名字
- class (可選 - 默認是通過反射得到的屬性類型):被關(guān)聯(lián)的類的名字闭树。
- cascade(級聯(lián)) (可選):表明操作是否從父對象級聯(lián)到被關(guān)聯(lián)的對象。
- constrained(約束) (可選):表明該類對應(yīng)的表對應(yīng)的數(shù)據(jù)庫表丰歌,和被關(guān)聯(lián)的對象所對應(yīng)的數(shù)據(jù)庫表之間姨蟋,通過一個外鍵引用對主鍵進行約束。
這個選項影響save()和delete()在級聯(lián)執(zhí)行時的先后順序
以及決定該關(guān)聯(lián)能否被委托(也在schema export tool中被使用). - fetch (可選 - 默認設(shè)置為選擇): 在外連接抓取或者序列選擇抓取選擇其一.
- property-ref (可選):指定關(guān)聯(lián)類的屬性名立帖,這個屬性將會和本類的主鍵相對應(yīng)眼溶。
如果沒有指定,會使用對方關(guān)聯(lián)類的主鍵晓勇。 - access (可選 - 默認是 property): Hibernate用來訪問屬性的策略堂飞。
- formula (可選):絕大多數(shù)一對一的關(guān)聯(lián)都指向其實體的主鍵。
在一些少見的情況中宵蕉, 你可能會指向其他的一個或多個字段酝静,或者是一個表達式,
這些情況下羡玛,你可以用一個SQL公式來表示别智。
(可以在org.hibernate.test.onetooneformula找到例子) - lazy (可選 - 默認為 proxy): 默認情況下,單點關(guān)聯(lián)是經(jīng)過代理的稼稿。lazy="no-proxy"指定此屬性應(yīng)該在實例變量第一次被訪問時應(yīng)該延遲抓缺¢弧(fetche lazily)(需要運行時字節(jié)碼的增強)讳窟。 lazy="false"指定此關(guān)聯(lián)總是被預(yù)先抓取。注意敞恋,如果constrained="false", 不可能使用代理丽啡,Hibernate會采取預(yù)先抓取硬猫!
- entity-name (可選): 被關(guān)聯(lián)的類的實體名补箍。
一對一
一個人對應(yīng)一張身份證,一張身份證對應(yīng)一個人
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zts.day05.one2one">
<class name="Person" table="tbl_person">
<id name="id" column="id">
<generator class="increment" />
</id>
<property name="name" />
<!--在主方配置一對一,property-ref="person"這個屬性意味著主方的主鍵配置從方的外鍵啸蜜,默認是主方的主鍵配置從方的主鍵 -->
<one-to-one name="card" class="Card" property-ref="person" />
</class>
</hibernate-mapping>
- <one-to-one name="card" class="Card" property-ref="person" />
- 在card.hbm.xml中配置
<one-to-one name="person" class="Person" constrained="true"></one-to-one>
同時由于一對一是特殊的多對一中多為唯一的特例所以針對關(guān)聯(lián)屬性我們也可以這樣寫:
<many-to-one name="person" class="Person" unique="true" column="p_id"/>
多對一
一個顧客對應(yīng)多個訂單坑雅,多個訂單對應(yīng)一個顧客
顧客
<!--關(guān)聯(lián)映射 false是延遲加載關(guān)聯(lián)映射 ,默認為true-->
<set name="orders" lazy="true" cascade="all">
<key column="c_id"></key>
<one-to-many class="Order" />
</set>
訂單
<!--關(guān)聯(lián)映射 -->
<many-to-one name="customer" class="Customer" column="c_id"></many-to-one>
多對多
一個學(xué)生可以選多門課程,一名課程可以有多名學(xué)生選擇
#######學(xué)生
<set name="courses" table="tbl_student_course">
<key column="s_id"></key>
<many-to-many class="Course" column="c_id"></many-to-many>
</set>
#######課程
<set name="students" table="tbl_student_course">
<key column="c_id"></key>
<many-to-many class="Student" column="s_id"></many-to-many>
</set>
我們必須在 set標(biāo)簽這里加入一個table屬性衬横,這樣就會默認幫我們加載這個表裹粤。不然系統(tǒng)會自動幫我創(chuàng)建兩個表。
兩個一對多
多對多我們可以看成是tbl_student對tbl_student_course(橋表)的一對多和tbl_course對tbl_student_course(橋表)的一對多蜂林。
#######學(xué)生
<set name="stucous">
<key column="s_id"></key>
<one-to-many class="Stucou" />
</set>
#######課程
<set name="stucous">
<key column="c_id"></key>
<one-to-many class="Stucou"/>
#######學(xué)生——課程
<many-to-one name="student" class="Student" column="s_id"/>
<many-to-one name="course" class="Course" column="c_id"/>
這樣寫的好處是:我們可以給橋表增加屬性比如:grade(分數(shù))遥诉,comment(評論)等等。
<set cascade="all",inverse="false"/>兩個屬性詳解
級聯(lián)操作
在映射文件中的關(guān)聯(lián)元素中都有一個cascade屬性噪叙,用來指定如果操縱與當(dāng)前對象關(guān)聯(lián)的其他對象矮锈。eg: cascade="all"
- none: 在保存,更新构眯,刪除當(dāng)前對象的時候忽略其他關(guān)聯(lián)的對象愕难。是cascade的默認值
- save-update: 當(dāng)通過Session的save(),update(),saveOrUpdate()方法來保存或者更新當(dāng)前對象的時候級聯(lián)保存所有關(guān)聯(lián)的臨時對象,級聯(lián)更新所有關(guān)聯(lián)的游離對象惫霸。
- delete: 當(dāng)通過Session的delete()方法刪除當(dāng)前對象的時候級聯(lián)刪除所有關(guān)聯(lián)的對象。
- all:包含save-update和delete的行為葱弟。
- delete-orphan:刪除所有和當(dāng)前對象解除關(guān)聯(lián)關(guān)系的對象壹店。(只能在set中配置)
- all-delete-orphan: 包含all和delete-orphan的行為
inverse:負責(zé)控制關(guān)系
默認inverse="false" 只能顯示在<set>放進行設(shè)置
inverse真正的作用是指定由哪一方來維護之間的關(guān)聯(lián)關(guān)系,當(dāng)一方指定inverse="false"那么這一方就有責(zé)任負責(zé)之間的關(guān)聯(lián)關(guān)系芝加。.需要將其中的一方inverse="true"
在一對多關(guān)系中硅卢,如果使用默認的inverse,那么意味著雙方都可以維護關(guān)聯(lián)關(guān)系藏杖,也就說在代碼中可以僅僅用主方來維護從方将塑,也可以用從方來維護主方,如果雙向維護將會有一次重復(fù)更新蝌麸。
在多對多關(guān)系中点寥,如果用雙方的外鍵來作為橋表的主鍵,只能一方來維護關(guān)聯(lián)關(guān)系来吩,意味著必須要將其中的一方設(shè)置為inverse="true"敢辩,不然將會造成主鍵沖突的異常蔽莱。