在上一部分我只講到如何通過數據庫中的表生成映射文件和 POJO。在這一部分中,我將講解映射文件。
先看看這張表:
在現實的車輛管理系統中,絕對不會把車輛信息和擁有人信息放在一張表中。應該是“一個擁有者”擁有一或多個“車輛”。來看看分解後的表,PEOPLE 表,設置 OWNER_ID 爲 主鍵:
AUTO_INFO 表,設置 AUTO_ID 爲 主鍵:
爲兩表配置主、外鍵關係,設置 PEOPLE 表爲主表:
爲兩表配置主、外鍵關係,設置 PEOPLE 表爲主表:
爲兩表配置主、外鍵關係,設置 PEOPLE 表爲主表:
打開 Eclipse,爲這兩張表生成映射文件。
AutoInfo.hbm.xml:
<?xml version="1.0"?> <hibernate-mapping package="bo"> |
<?xml version="1.0"?> <hibernate-mapping package="bo"> |
People.hbm.xml:
<?xml version="1.0"?> <hibernate-mapping package="bo"> |
<?xml version="1.0"?> <hibernate-mapping package="bo"> |
以 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"
property column="LICENSE_PLATE" length="20" name="LicensePlate" not-null="false" type="string"
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" 定義了一個持久化對象與另一個持久化對象的關係,這種關聯模型是多對一的關聯。應用在車輛管理系統中,代表着多臺車輛由一個擁有者擁有。分別表示關聯類的名字(由反射機制得到類型)、屬性名稱、非空狀態、字段名。
分析完 AutoInfo.hbm.xml 後,再來看看 People.hbm.xml。大部分內容都已經在前面出現過,不同的地方是:
<set inverse="true" name="AutoInfoSet"> |
<set inverse="true" name="AutoInfoSet"> |
在車輛管理系統中,代表着一個擁有者擁有多臺車輛。以 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://blog.csdn.net/rosen)
(請注意!引用、轉貼本文應註明原作者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen)