回想一些我們?cè)跊](méi)有學(xué)習(xí)ssh的時(shí)候,我們建立數(shù)據(jù)庫(kù)的表時(shí),首先是數(shù)據(jù)庫(kù)建模E-R圖,然后再通過(guò)實(shí)體模型來(lái)建立關(guān)系模型,再建立相應(yīng)的表。實(shí)體間存在三種關(guān)系,一對(duì)一,一對(duì)多(或者說(shuō)多對(duì)一),多對(duì)多。而如今我們要根據(jù)類來(lái)映射相應(yīng)的表,那只能是通過(guò)類與類之間的關(guān)系加上映射文件來(lái)映射數(shù)據(jù)庫(kù)的表。我們學(xué)習(xí)UML建模,類與類之間存在五種關(guān)系,繼承,實(shí)現(xiàn),關(guān)聯(lián),依賴,聚合/組合,在hibernate中實(shí)體類之間的關(guān)系也是如此,對(duì)于不同的關(guān)系對(duì)應(yīng)的代碼實(shí)現(xiàn)我們已經(jīng)很熟悉了,所以對(duì)于實(shí)體類是復(fù)習(xí)的知識(shí)。
創(chuàng)新互聯(lián)專注于鹿泉企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站定制開(kāi)發(fā)。鹿泉網(wǎng)站建設(shè)公司,為鹿泉等地區(qū)提供建站服務(wù)。全流程按需策劃,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
Hibernate的本質(zhì)就是對(duì)象關(guān)系映射(ObjectRelational Mapping),ORM實(shí)現(xiàn)了將對(duì)象數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中,以前我們對(duì)關(guān)系表進(jìn)行操作,執(zhí)行增刪改查等任務(wù),現(xiàn)在我們不再對(duì)關(guān)系表進(jìn)行操作,而是直接對(duì)對(duì)象操作。hibernate中的ORM映射文件通常以.hbm.xml作為后綴。使用這個(gè)映射文件不僅易讀,而且可以手工修改,也可以通過(guò)一些工具來(lái)生成映射文檔。下面將對(duì)hibernate中的映射進(jìn)行介紹。
Hibernate映射分類,如下圖所示。

1 基本類映射
根據(jù)實(shí)體類創(chuàng)建相應(yīng)的表,這種簡(jiǎn)單的關(guān)系為hibernate基本映射。
User1實(shí)體類代碼如下:
//user實(shí)體。
public classUser1 {
//用戶編號(hào)。
private String id;
//名字。
private String name;
//密碼。
private String password;
//創(chuàng)建日期。
private Date createTime;
//失效時(shí)間。
private Date expireTime;
public String getId() {
return id;
}
// publicvoid setId(String id) {
// this.id= id;
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(Stringpassword) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(DatecreateTime) {
this.createTime = createTime;
}
public Date getExpireTime() {
return expireTime;
}
public void setExpireTime(DateexpireTime) {
this.expireTime = expireTime;
}
}
User1.hbm.xml映射文件如下所示:
<hibernate-mapping package="com.bjpowernode.hibernate">
<class name="User1" table="t_user1">
<id name="id"column="user_id" length="32"access="field">
<generator class="uuid" />
</id>
<!-- 設(shè)置主鍵不能重復(fù)和不能為空的屬性. -->
<property name="name" length="30"unique="true" not-null="true"/>
<property name="password"/>
<property name="createTime" type="date" column="create_time"/>
<property name="expireTime"/>
</class>
</hibernate-mapping> 通過(guò)User1.hbm.xml映射文件將User1對(duì)象轉(zhuǎn)換為關(guān)系數(shù)據(jù)庫(kù)中的表t_user1。
轉(zhuǎn)換出的結(jié)果如下所示:
2 對(duì)象關(guān)系映射
2.1 多對(duì)一關(guān)聯(lián)映射(單向)
例如用戶和組的關(guān)系就是多對(duì)一的關(guān)系,多個(gè)用戶對(duì)應(yīng)一個(gè)組。

將實(shí)體映射成表,將對(duì)應(yīng)的實(shí)體映射成表。對(duì)應(yīng)的屬性映射成表字段。
多對(duì)一關(guān)聯(lián)映射是在多的一端來(lái)維護(hù)關(guān)聯(lián)字段,在我們這個(gè)例子中也就是在用戶一端來(lái)維護(hù)關(guān)系字段。
User.hbm.xml文件。
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.User" table="t_user" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="group" column="groupid"cascade="save-update"></many-to-one>
</class>
</hibernate-mapping> Group.hbm.xml文件。
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.Group" table="t_group">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class>
</hibernate-mapping> 在這里我們看的代碼就看*.hbm.mlx代碼,因?yàn)閷?duì)于類之間的關(guān)聯(lián),在實(shí)現(xiàn)時(shí),一個(gè)類作為另一個(gè)類的私有成員,這一點(diǎn)在學(xué)UML建模的時(shí)候我們都懂了,在這里主要看的是ORM的M,也就是*.hbm.xml文件。
2.2 一對(duì)一關(guān)聯(lián)映射
一對(duì)一關(guān)聯(lián)映射在實(shí)際生活中是比較常見(jiàn)的,如人與家庭住址的關(guān)系,通過(guò)人這個(gè)對(duì)象可以找到他家庭住址相關(guān)的內(nèi)容。
2.2.1 一對(duì)一映射(單向主鍵關(guān)聯(lián))

單向一對(duì)一主鍵關(guān)聯(lián),靠的是它們的主鍵相等,從Person中能看到IdCard,也就是把t_idCard中的主鍵拿過(guò)來(lái)當(dāng)做t_Pseron的主鍵。
Xml文件中:
<class name="com.bjpowernode.hibernate.Person"table="t_person" >
<id name="id">
<!-- 采用foreign生成策略,foreign會(huì)取得關(guān)聯(lián)對(duì)象的標(biāo)識(shí) -->
<generator class="foreign" >
<!--property指的是關(guān)聯(lián)對(duì)象。 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- 一對(duì)一關(guān)聯(lián)映射,主鍵關(guān)聯(lián). -->
<!--
one-to-one標(biāo)簽指示hibernate如何加載其關(guān)聯(lián)對(duì)象,默認(rèn)根據(jù)主鍵加載.
也就是拿到關(guān)系字段值,根據(jù)對(duì)端的主鍵來(lái)加載關(guān)聯(lián)對(duì)象.
constrained="true",表示當(dāng)前主鍵(Person的主鍵)還是一個(gè)外鍵 .
參照了對(duì)端的主鍵(IdCard的主鍵),也就是會(huì)生成外鍵約束語(yǔ)句.
-->
<one-to-one name="idCard" constrained="true"/>
</class> <hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" >
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping> 一對(duì)一的關(guān)系是通過(guò)one-to-one元素定義的。
2.2.2 一對(duì)一映射(雙向主鍵關(guān)聯(lián))
一對(duì)一雙向主鍵關(guān)聯(lián)與一對(duì)一單向主鍵關(guān)聯(lián)的區(qū)別就是,一對(duì)一單向主鍵關(guān)聯(lián),在person端能看到idCard,而idCard不能看到Person端。而雙向關(guān)聯(lián)就是在idCard端也能看到person,也就是不但在Person.hbm.xml中加上<one-to-one>標(biāo)簽,同時(shí)在IdCard.hbm.xml文件中加上<one-to-one>標(biāo)簽。代碼如下所示。
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" >
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>
</hibernate-mapping>

2.2.3 一對(duì)一映射(單向唯一外鍵關(guān)聯(lián))
一對(duì)一單向唯一外鍵關(guān)聯(lián),也就是多對(duì)一關(guān)聯(lián)的特例,把多的一端限制為一,就是一對(duì)一唯一外鍵關(guān)聯(lián)。同多對(duì)一一樣,在一端加入另一端的并采用<many-to-one>標(biāo)簽,通過(guò)unique="true",這樣來(lái)限制了多的一端為一。
先上代碼。
IdCard.hbm.xml
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" >
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping> Person.hbm.xml
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.Person" table="t_person" >
<id name="id">
<!-- 采用foreign生成策略,foreign會(huì)取得關(guān)聯(lián)對(duì)象的標(biāo)識(shí) -->
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"></many-to-one>
</class>
</hibernate-mapping> 圖如下所示:
在t_pserson端加上一個(gè)外鍵字段idCard,限制idCard的唯一性就是一對(duì)一唯一外鍵關(guān)聯(lián)。
2.2.4 一對(duì)一映射(雙向唯一外鍵關(guān)聯(lián))
一對(duì)一唯一外鍵單向關(guān)聯(lián)我們已經(jīng)了解了,雙向反過(guò)來(lái)就是在沒(méi)有的一端加上就可以了。
我們的IdCard.hbm.xml中采用<one-to-one>標(biāo)簽。
<hibernate-mapping package="org.hibernate.auction">
<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard" >
<id name="id">
<generator class="native" />
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="idCard"></one-to-one>
</class>
</hibernate-mapping> 而person.hbm.xml同一對(duì)一唯一外鍵單向關(guān)聯(lián)一樣。
<class name="com.bjpowernode.hibernate.Person" table="t_person" >
<id name="id">
<!-- 采用foreign生成策略,foreign會(huì)取得關(guān)聯(lián)對(duì)象的標(biāo)識(shí) -->
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"></many-to-one>
</class>
從上述中可以總結(jié)出,對(duì)于一對(duì)一關(guān)聯(lián)映射,主鍵關(guān)聯(lián)和唯一外鍵關(guān)聯(lián)單向和雙向產(chǎn)生出的表結(jié)構(gòu)是一樣的,不同的是在加載的時(shí)候不同。也就是一對(duì)一雙向關(guān)聯(lián)和一對(duì)一單向關(guān)聯(lián)的相比,只是改變了一對(duì)一關(guān)聯(lián)映射的加載,而沒(méi)有改變存儲(chǔ)。
2.3 一對(duì)多關(guān)聯(lián)映射
2.3.1 一對(duì)多關(guān)聯(lián)映射(單向)
上面我們介紹了多對(duì)一,我們反過(guò)來(lái)看一對(duì)多不就是多對(duì)一嗎?那還用再進(jìn)行不同的映射嗎?有什么差別嗎?一對(duì)多和多對(duì)一映射原理是一致的,存儲(chǔ)是相同的,也就是生成的數(shù)據(jù)庫(kù)的表是一樣的,他們之間不同的是維護(hù)的關(guān)系不同。
他們之間不同點(diǎn)是維護(hù)的關(guān)系不同
代碼如下所示。
Class.hbm.xml
<class name="com.bjpowernode.hibernate.Classes" table="t_Classes" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="students">
<!--
<keycolumn="classesid" not-null="true"/>
-->
<key column="classesid" />
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class> Students.hbm.xml
<class name="com.bjpowernode.hibernate.Student" table="t_student" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class>從班級(jí)能看到學(xué)生,是班級(jí)來(lái)維護(hù)關(guān)系,不是學(xué)生來(lái)維護(hù)關(guān)系,學(xué)生不知道自己是哪個(gè)班,所以在存儲(chǔ)學(xué)生的時(shí)候,班級(jí)的代碼不知道。為了更新學(xué)生是哪個(gè)班級(jí)的要發(fā)出很多update語(yǔ)句來(lái)告訴學(xué)生是哪個(gè)班級(jí)的。當(dāng)我們?cè)O(shè)置classesid not-null=“true”時(shí),則將無(wú)法保存數(shù)據(jù),解決辦法我們改為雙向關(guān)聯(lián)映射。
2.3.2 一對(duì)多關(guān)聯(lián)映射(雙向)
為了解決一對(duì)多單向可能存在的問(wèn)題,我們采用雙向一對(duì)多,每一方都能維護(hù)對(duì)方。

一對(duì)多雙向關(guān)聯(lián)映射方式:
!~注意<key>標(biāo)簽和<many-to-one>標(biāo)簽加入字段保持一致,否則會(huì)產(chǎn)生數(shù)據(jù)混亂。
代碼如下所示。
<class name="com.bjpowernode.hibernate.Classes" table="t_Classes" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="students" inverse="true">
<!--
<keycolumn="classesid" not-null="true"/>
-->
<key column="classesid" />
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class> <class name="com.bjpowernode.hibernate.Student" table="t_student" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<many-to-one name="classes"column="classesid"/>
</class> 注意:Inverse屬性
1、 Inverse中文意思為相反的,反轉(zhuǎn)。在hibernate中inverse可以用在一對(duì)多和多對(duì)多雙向關(guān)聯(lián)上,inverse默認(rèn)是false,為false的時(shí)候表示本端可以維護(hù)關(guān)系,如果inverse為true,則本端不能維護(hù)關(guān)系,會(huì)交給另一端維護(hù)關(guān)系,本端失效,所以在一對(duì)多關(guān)聯(lián)映射我們通常在多的一端維護(hù)關(guān)系,讓一的一端失效。
2、Inverse是控制方向上的反轉(zhuǎn),只影響存儲(chǔ)。
比較一對(duì)多單向和雙向映射,從存儲(chǔ)結(jié)構(gòu)上看沒(méi)有什么區(qū)別,但是從配置文件上看,一對(duì)多雙向比一對(duì)多單向,一對(duì)多雙向關(guān)聯(lián)的配置文件中在多的一端的配置文件上存在<many-to-one>相關(guān)配置,即保證多對(duì)一的映射。
2.4 多對(duì)多關(guān)聯(lián)映射
2.4.1 多對(duì)多關(guān)聯(lián)映射(單向)
多對(duì)多對(duì)象關(guān)系映射,需要加入一張新表完成基本映射。如下圖所示。

代碼。
Role.hbm.xml
<class name="com.bjpowernode.hibernate.Role" table="t_role">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
</class> User.hbm.xml
<class name="com.bjpowernode.hibernate.User" table="t_user" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="user_id"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/>
</set>
</class> 2.4.2 多對(duì)多關(guān)聯(lián)映射(雙向)
雙向多對(duì)多對(duì)象關(guān)系映射,是兩端都能將對(duì)方加載上來(lái),雙向都需要加上標(biāo)簽映射。
要注意:

代碼如下所示。
Role.hbm.xml
<class name="com.bjpowernode.hibernate.Role" table="t_role">
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="users" table="t_user_role">
<key column="role_id"/>
<many-to-many class="com.bjpowernode.hibernate.User" column="user_id"/>
</set>
</class> User.hbm.xml
<class name="com.bjpowernode.hibernate.User"table="t_user" >
<id name="id">
<generator class="native" />
</id>
<property name="name"/>
<set name="roles" table="t_user_role">
<key column="user_id"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/>
</set>
</class> 區(qū)別:?jiǎn)蜗蚨鄬?duì)多和雙向多對(duì)多存儲(chǔ)結(jié)構(gòu)沒(méi)有任何的區(qū)別,但他們的映射文件是有區(qū)別的,加載過(guò)程是不同的。
3 關(guān)系映射總結(jié)
綜上所述,可以看出,同一類映射,無(wú)論是單向還是雙向,他們的存儲(chǔ)結(jié)構(gòu)是相同的,之所以映射文件不同,是因?yàn)榧虞d時(shí)不同(在增刪改時(shí))。
無(wú)論是多對(duì)一、一對(duì)多、一對(duì)一還是多對(duì)一,A對(duì)B,A就是主動(dòng)方,A主動(dòng)想要了解B的情況,這樣把B設(shè)置到A端。而雙向,也就是A對(duì)B,A想了解B的信息,而B(niǎo)也想了解A的信息,那就要同時(shí)把A設(shè)置到B端了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
名稱欄目:Hibernate映射之基本類映射和對(duì)象關(guān)系映射詳解
當(dāng)前URL:http://www.chinadenli.net/article6/gicpig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、定制網(wǎng)站、Google、網(wǎng)站制作、網(wǎng)站排名、定制開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)