[置頂] 【SSH進階之路】Hibernate映射――一對一雙向關聯映射(六)
來源:程序員人生 發布時間:2014-11-13 08:59:31 閱讀次數:2782次
上篇博文【SSH進階之路】Hibernate映照――1對1單向關聯映照(5),我們介紹了1對1的單向關聯映照,單向是指只能從人(Person)這端加載身份證端(IdCard),但是反過來,不能從身份證端加載人得信息。如圖所示:

關鍵緣由在于對象模型具有方向性:
單向:1端只能加載另外一端,不能反過來。
雙向:兩端都可以加載另外一端。
問題來了:如何我們想從身份證端(IdCard)加載人(Person),怎樣辦呢?
下面我們開始介紹1對1的雙向關聯映照。
映照原理
雙向關聯映照與單向關聯映照的原理是1樣的,雙向關聯映照并不影響存儲,只影響加載。所以,雙向關聯映照和單向關聯映照的關系模型是1樣的即http://www.vxbq.cn/db/的表結構是1樣的,只是IdCard的實體類和配置文件(IdCard.hbm.xml)產生了1點點變化。
對象模型

從上圖中可以看出:
1、1個人只有1張身份證,唯1的1個身份證號,對象之間是1對1的關系;
2、兩個對象得關系保護還是由person端決定(由于關系只能由1端保護主鍵,否則關系就亂了)。
根據上面的對象模型,我們可以看到Person端沒有變化,但是要在IdCard端加上Person的援用,例如Person和IdCard實體類以下。
Person
package com.liang.hibernate;
public class Person {
private int id;
private String name;
private IdCard idCard;
public IdCard getIdCard() {
return idCard;
}
public void setIdCard(IdCard idCard) {
this.idCard = idCard;
}
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;
}
}
IdCard
package com.liang.hibernate;
public class IdCard {
private int id;
private String cardNo;
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
}
不管是單向關聯映照還是雙向關聯映照,他們都屬于1對1關聯映照,只是他們主鍵的生成策略不同,分為主鍵關聯映照和唯1外鍵關聯映照。
由于它們都屬于1對1關聯映照,所以,Hibernate封裝雙向關聯映照時,主鍵關鍵映照和唯1外鍵關聯映照的加載策略1樣,都采取的是1對1<one-to-one name=""></one-to-one>,只是屬性設置不1致,所以,下面我們分開來看IdCard的配置文件。
分類:
主鍵關聯映照
同1對1單向關聯映照類似,主鍵關聯即利用主鍵進行關聯,關聯主鍵的值相同。下面我們看1下映照文件:
IdCard.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping package="com.liang.hibernate">
<class name="IdCard" table="t_idCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="cardNo"></property>
<!-- 怎樣加載對象,抓取策略:join聯合查詢(默許),select:1條條的查詢 -->
<one-to-one name="person" class="Person" fetch="join"></one-to-one>
</class>
</hibernate-mapping>
Person.hbm.xml,同1對1單向主鍵關聯映照1樣
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping package="com.liang.hibernate">
<class name="Person" table="t_person">
<id name="id">
<!-- 采取foreign生成策略,forgeign會獲得關聯對象的標識 -->
<generator class="foreign" >
<param name="property">idCard</param>
</generator>
</id>
<property name="name"></property>
<!--
one-to-one唆使hibernate如何加載其關聯對象,默許根據主鍵加載
也就是拿到關系字段值,根據對真個主鍵來加載關聯對象
constrained="true"表示,當前主鍵(person的主鍵)還是1個外鍵
參照了對真個主鍵(IdCard的主鍵),也就是會生成外鍵束縛語句
-->
<one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
生成的表結構

唯1外鍵關聯映照
1對1雙向關聯映照的外鍵關聯映照也與1對1單向關聯映照的外鍵關聯映照類似,在其1對1的指向端(Person)存在1個唯1外鍵,該唯1外鍵與被指向端(IdCard)相干聯,關聯主鍵的值相同。下面我們看1下映照文件:
IdCard.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping package="com.liang.hibernate">
<class name="IdCard" table="t_idCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="cardNo"></property>
<!-- 1對1唯1外鍵關聯雙向采取<one-to-one>標簽來映照,必須指定<one-to-one>
標簽中的property-ref屬性為關系字段的名稱
-->
<one-to-one name="person" class="Person" property-ref="idCard"></one-to-one>
</class>
</hibernate-mapping>
Person.hbm.xml,同1對1單向唯1外鍵關聯映照1樣
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping package="com.liang.hibernate">
<class name="Person" table="t_person">
<id name="id">
<generator class="native" ></generator>
</id>
<property name="name"></property>
<!-- 由于它是1對1的唯1外鍵關聯,它是多對1關聯的特例,注釋可以直接寫成多對1關聯-->
<!-- idCard屬性,表達的是本對象與IdCard的多對1關系。 -->
<many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>
</class>
</hibernate-mapping>
生成的表結構

對照
1對1單向和雙向關聯映照的區分正是對象模型和關系模型的區分之1。
對象模型:有方向性。它究竟是單向還是雙向是由對象模型決定的即配置文件決定。
關系模型:沒有方向性或說是雙向的。從任何1端都可以加載另外一端。
下載
以上內容,只證明了1對1雙向關聯映照不影響存儲即沒有改變表結構,但不能證明關聯是雙向的,需要寫相應的測試用例,我們以源碼的情勢給大家。源碼下載
總結
1對1雙向關聯映照其實不是必須的,是由需求下決定的。如果沒有這樣的需求,用戶也沒有要求,系統也不需要,就沒有必要建立雙向的關聯映照。
下篇博文,我們介紹多對多單向關聯映照,謝謝關注。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈