??? 在上一部分我只講到如何通過數據庫中的表生成映射文件和 POJO 。在這一部分中,我將講解映射文件。
?
??? 先看看這張表:
??? ??????????
在現實的車輛管理系統中,絕對不會把車輛信息和擁有人信息放在一張表中。應該是“一個擁有者”擁有一或多個“車輛”。來看看分解后的表, PEOPLE 表,設置 OWNER_ID 為 主鍵:
??? AUTO_INFO 表,設置 AUTO_ID 為 主鍵:
??? 為兩表配置主、外鍵關系,設置 PEOPLE 表為主表:
???? ????
打開 Eclipse ,為這兩張表生成映射文件。
AutoInfo.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
?????? "-//Hibernate/Hibernate Mapping DTD//EN"
?????? "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping package="bo">
?????? <class name="AutoInfo" table="AUTO_INFO">
????????????? <id
???????????????????? column="AUTO_ID"
???????????????????? name="Id"
???????????????????? type="integer"
????????????? >
???????????????????? <generator class="vm" />
????????????? </id>
????????????? <property
???????????????????? column="LICENSE_PLATE"
???????????????????? length="20"
???????????????????? name="LicensePlate"
???????????????????? not-null="false"
???????????????????? type="string"
????????????? ?/>
????????????? <many-to-one
???????????????????? class="People"
???????????????????? name="OwnerNo"
???????????????????? not-null="true"
???????????????????? <column name="OWNER_NO" />
????????????? </many-to-one>
?????? </class>
</hibernate-mapping>
People.hbm.xml :
?????? <class name="People" table="PEOPLE">
???????????????????? column="OWNER_ID"
???????????????????? column="NAME"
???????????????????? length="50"
???????????????????? name="Name"
???????????????????? column="ADDRESS"
???????????????????? length="1000"
???????????????????? name="Address"
????????????? <set inverse="true" name="AutoInfoSet">
???????????????????? <key column="OWNER_NO" />
???????????????????? <one-to-many class="AutoInfo" />
????????????? </set>
以 AutoInfo.hbm.xml 作為詳細分析的例子:
DOCTYPE 定義了這個 XML 文件規范 DTD,可以通過后面的 URL 獲取,或者在 Hibernate 的 CLASSPATH 中獲取。
hibernate-mapping package="bo" 定義了POJO所存在的包 “bo”。
class name="AutoInfo" table="AUTO_INFO" 定義了 POJO 的名稱“AutoInfo”和數據庫中的表名“AUTO_INFO”。
id column="AUTO_ID" name="Id" type="integer" 定義了數據庫表中的主鍵字段,為相應的 POJO 的每個實例包含唯一標識。column為數據庫表字段名,name標識屬性名字,type說明在 POJO 中的類型。另外,還有一個重要標識:unsaved-value,將會在以后用到。
Generator 為每個 POJO 的實例提供唯一標識。一般情況,我們使用 “ native ” 。class表示采用由生成器接口 net.sf.hibernate.id.IdentifierGenerator 實現的某個實例,其中包括:
“ assigned ”
主鍵由外部程序負責生成,在 save() 之前指定一個。
“ hilo ”
通過 hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表或字段提供高位值來源。
“ seqhilo ”
與 hilo 類似,通過 hi/lo 算法實現的主鍵生成機制,需要數據庫中的 Sequence ,適用于支持 Sequence 的數據庫,如 Oracle 。
“ increment ”
主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存著當前的最大值,之后每次需要生成主鍵的時候將此值加 1 作為主鍵。這種方式可能產生的問題是:不能在集群下使用。
“ identity ”
采用數據庫提供的主鍵生成機制。如 DB2 、 SQL Server 、 MySQL 中的主鍵生成機制。
“ sequence ”
采用數據庫提供的 sequence 機制生成主鍵。如 Oralce 中的 Sequence 。
“ native ”
由 Hibernate 根據使用的數據庫自行判斷采用 identity 、 hilo 、 sequence 其中一種作為主鍵生成方式。
“ uuid.hex ”
由 Hibernate 基于 128 位 UUID 算法 生成 16 進制數值(編碼后以長度 32 的字符串表示)作為主鍵。
“ uuid.string ”
與 uuid.hex 類似,只是生成的主鍵未進行編碼(長度 16 ),不能應用在 PostgreSQL 數據庫中 。
“ foreign ”
使用另外一個相關聯的對象的標識符作為主鍵。
property column="LICENSE_PLATE" length="20" name="LicensePlate" not-null="false" type="string" 定義了 POJO 中的屬性,分別表示數據庫表中的字段、長度、POJO 屬性名稱以及類型、非空狀態。
many-to-one class="People" name="OwnerNo " not-null="true" column name="OWNER_NO" 定義了一個持久化對象與另一個持久化對象的關系,這種關聯模型是多對一的關聯。應用在車輛管理系統中,代表著多臺車輛由一個擁有者擁有。分別表示關聯類的名字(由反射機制得到類型)、屬性名稱、非空狀態、字段名。
分析完 AutoInfo.hbm.xml 后,再來看看 People.hbm.xml 。大部分內容都已經在前面出現過,不同的地方是:
<set inverse="true" name="AutoInfoSet">
????????????? <key column="OWNER_NO" />
????????????? <one-to-many class="AutoInfo" />
</set>
在車輛管理系統中,代表著一個擁有者擁有多臺車輛。以 java.util.Set類型表示。 inverse用于標識雙向關聯中的 被動方一端。 inverse=false 的一方(主控方)負責維護關聯關系 ;在 車輛管理系統 中, AutoInfo 作為主控方,應該把它設為“ true ”。這就好比你(被動方 one )在某個聚會上散發了許多名片,但是有可能你不清楚接收者(主動方 many )的具體背景;這個不要緊,接收者在必要的時候會和你聯系就是了(主動維護關系)。
另外在 set 節點的屬性中還有一個重要標識 : 級聯( cascade )關系,指明哪些操作(insert、update、delete)會從 主控方 對象級聯到關聯的對象。
可選值:
all: save() 、 saveOrUpdate() 、 update() 、 delete() 均進行級聯操作。
none : 所有情況下均不進行級聯操作。
save-update: 在執行 save() 、 saveOrUpdate() 、 update() 時進行級聯操作。
delete : 只在執行 delete() 時進行級聯操作。
級聯( cascade )在 Hibernate 映射關系中是個非常重要的概念。它指的是當主控對象調用 save-update 或 delete 方法時,是否同時對關聯對象(被動方)進行 save-update 或 delete 。在這個映射文件中,當擁有者( People )被更新或者刪除時,其所關聯的車輛( AutoInfo )可以被修改或刪除,所以應該把級聯關系設置為 cascade=”all” 。
請注意!引用、轉貼本文應注明原作者:Rosen Jiang 以及出處: http://www.tkk7.com/rosen
Powered by: BlogJava Copyright © Rosen