




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、對(duì)象/關(guān)系數(shù)據(jù)庫(kù)映射基礎(chǔ)(Basic O/R Mapping5.1. 映射定義(Mapping declaration)對(duì)象和關(guān)系數(shù)據(jù)庫(kù)之間的映射通常是用一個(gè)XML文檔(XML document來(lái)定義的。這個(gè)映射文檔被設(shè)計(jì)為易讀的, 并且可以手工修改。映射語(yǔ)言是以Java為中心,這意味著映射文檔是按照持久化類的定義來(lái)創(chuàng)建的, 而非表的定義。 請(qǐng)注意,雖然很多Hibernate用戶選擇手寫XML映射文檔,但也有一些工具可以用來(lái)生成映射文檔, 包括XDoclet,Middlegen和AndroMDA。 讓我們從一個(gè)映射的例子開始: "-/Hibernate/Hibernate
2、Mapping DTD 3.0/EN"table="cats"discriminator-value="C">type="character"/>type="date" not-null="true" update="false"/>not-null="true"update="false"/>not-null="true" update="false"/>
3、column="litterId"update="false"/>column="mother_id"update="false"/>inverse="true"order-by="litter_id">discriminator-value="D">type="string"/>我們現(xiàn)在開始討論映射文檔的內(nèi)容。我們只描述Hibernate在運(yùn)行時(shí)用到的文檔元素和屬性。 映射文檔還包括一些額外的可選屬性和元
4、素,它們?cè)谑褂胹chema導(dǎo)出工具的時(shí)候會(huì)影響導(dǎo)出的數(shù)據(jù)庫(kù)schema結(jié)果。 (比如, not-null 屬性。) 所有的XML映射都需要定義如上所示的doctype。DTD可以從上述URL中獲取, 也可以從目錄中、 或hibernate.jar文件中找到。Hibernate總是會(huì)首先在它的classptah中搜索DTD文件。 如果你發(fā)現(xiàn)它是通過(guò)連接Internet查找DTD文件,就對(duì)照你的classpath目錄檢查XML文件里的DTD聲明。 這個(gè)元素包括一些可選的屬性。schema和catalog屬性, 指明了這個(gè)映射所連接(refer)的表所在的schema和/或catalog名稱。 假若
5、指定了這個(gè)屬性,表名會(huì)加上所指定的schema和catalog的名字?jǐn)U展為全限定名。假若沒有指定,表名就不會(huì)使用全限定名。 default-cascade指定了未明確注明cascade屬性的Java屬性和 集合類Hibernate會(huì)采取什么樣的默認(rèn)級(jí)聯(lián)風(fēng)格。auto-import屬性默認(rèn)讓我們?cè)诓樵冋Z(yǔ)言中可以使用 非全限定名的類名。 schema="schemaName" (1catalog="catalogName" (2default-cascade="cascade_style" (3default-access="f
6、ield|property|ClassName" (4default-lazy="true|false" (5auto-import="true|false" (6package="" (7/>(1schema (可選: 數(shù)據(jù)庫(kù)schema的名稱。 (2catalog (可選: 數(shù)據(jù)庫(kù)catalog的名稱。 (3default-cascade (可選 - 默認(rèn)為 none: 默認(rèn)的級(jí)聯(lián)風(fēng)格。 (4default-access (可選 - 默認(rèn)為 property: Hibernate用來(lái)訪問所有
7、屬性的策略??梢酝ㄟ^(guò)實(shí)現(xiàn)PropertyAccessor接口 自定義。 (5default-lazy (可選 - 默認(rèn)為 true: 指定了未明確注明lazy屬性的Java屬性和集合類, Hibernate會(huì)采取什么樣的默認(rèn)加載風(fēng)格。 (6auto-import (可選 - 默認(rèn)為 true: 指定我們是否可以在查詢語(yǔ)言中使用非全限定的類名(僅限于本映射文件中的類)。 (7package (可選: 指定一個(gè)包前綴,如果在映射文檔中沒有指定全限定的類名, 就使用這個(gè)作為包名。 假若你有兩個(gè)持久化類,它們的非全限定名是一樣的(就是兩個(gè)類的名字一樣,所在的包不一樣-譯者注), 你應(yīng)該設(shè)置auto-i
8、mport="false"。如果你把一個(gè)“import過(guò)”的名字同時(shí)對(duì)應(yīng)兩個(gè)類, Hibernate會(huì)拋出一個(gè)異常。 注意hibernate-mapping 元素允許你嵌套多個(gè)如上所示的 映射。但是最好的做法(也許一些工具需要的)是一個(gè) 持久化類(或一個(gè)類的繼承層次)對(duì)應(yīng)一個(gè)映射文件,并以持久化的超類名稱命名,例如: , ,或者如果使用繼承,。 你可以使用class元素來(lái)定義一個(gè)持久化類: name="ClassName" (1table="tableName" (2discriminator-value="discrimi
9、nator_value" (3mutable="true|false" (4schema="owner" (5catalog="catalog" (6proxy="ProxyInterface" (7dynamic-update="true|false" (8dynamic-insert="true|false" (9select-before-update="true|false" (10polymorphism="implicit|
10、explicit" (11where="arbitrary sql where condition" (12persister="PersisterClass" (13batch-size="N" (14optimistic-lock="none|version|dirty|all" (15lazy="true|false" (16entity-name="EntityName" (17check="arbitrary sql check conditio
11、n" (18rowid="rowid" (19subselect="SQL expression" (20abstract="true|false" (21node="element-name"/>(1name (可選: 持久化類(或者接口)的Java全限定名。 如果這個(gè)屬性不存在,Hibernate將假定這是一個(gè)非POJO的實(shí)體映射。 (2table (可選 - 默認(rèn)是類的非全限定名: 對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名。 (3discriminator-value (可選 - 默認(rèn)和類名一樣: 一個(gè)用于區(qū)分不同的
12、子類的值,在多態(tài)行為時(shí)使用。它可以接受的值包括 null 和 not null。 (4mutable (可選,默認(rèn)值為true: 表明該類的實(shí)例是可變的或者不可變的。 (5schema (可選: 覆蓋在根 元素中指定的schema名字。 (6catalog (可選: 覆蓋在根 元素中指定的catalog名字。 (7proxy (可選: 指定一個(gè)接口,在延遲裝載時(shí)作為代理使用。 你可以在這里使用該類自己的名字。 (8dynamic-update (可選, 默認(rèn)為 false: 指定用于UPDATE 的SQL將會(huì)在運(yùn)行時(shí)動(dòng)態(tài)生成,并且只更新那些改變過(guò)的字段。 (9dynamic-insert (可
13、選, 默認(rèn)為 false: 指定用于INSERT的 SQL 將會(huì)在運(yùn)行時(shí)動(dòng)態(tài)生成,并且只包含那些非空值字段。 (10select-before-update (可選, 默認(rèn)為 false: 指定Hibernate除非確定對(duì)象真正被修改了(如果該值為true譯注),否則不會(huì)執(zhí)行SQL UPDATE操作。在特定場(chǎng)合(實(shí)際上,它只在一個(gè)瞬時(shí)對(duì)象(transient object)關(guān)聯(lián)到一個(gè) 新的session中時(shí)執(zhí)行的update(中生效),這說(shuō)明Hibernate會(huì)在UPDATE 之前執(zhí)行一次額外的SQL SELECT操作,來(lái)決定是否應(yīng)該執(zhí)行 UPDATE。 (11polymorphism(多態(tài))
14、 (可選, 默認(rèn)值為 implicit (隱式 : 界定是隱式還是顯式的使用多態(tài)查詢(這只在Hibernate的具體表繼承策略中用到譯注)。 (12where (可選 指定一個(gè)附加的SQLWHERE 條件, 在抓取這個(gè)類的對(duì)象時(shí)會(huì)一直增加這個(gè)條件。 (13persister (可選: 指定一個(gè)定制的ClassPersister。 (14batch-size (可選,默認(rèn)是1 指定一個(gè)用于 根據(jù)標(biāo)識(shí)符(identifier)抓取實(shí)例時(shí)使用的"batch size"(批次抓取數(shù)量)。 (15optimistic-lock(樂觀鎖定) (可選,默認(rèn)是version: 決定樂觀鎖定
15、的策略。 (16lazy (可選: 通過(guò)設(shè)置lazy="false", 所有的延遲加載(Lazy fetching)功能將被全部禁用(disabled)。 (17entity-name (可選,默認(rèn)為類名: Hibernate3允許一個(gè)類進(jìn)行多次映射( 前提是映射到不同的表),并且允許使用Maps或XML代替Java層次的實(shí)體映射 (也就是實(shí)現(xiàn)動(dòng)態(tài)領(lǐng)域模型,不用寫持久化類譯注)。 更多信息請(qǐng)看第 4.4 節(jié) “動(dòng)態(tài)模型(Dynamic models” and 第 18 章 XML映射。 (18check (可選: 這是一個(gè)SQL表達(dá)式
16、, 用于為自動(dòng)生成的schema添加多行(multi-row)約束檢查。 (19rowid (可選: Hibernate可以使用數(shù)據(jù)庫(kù)支持的所謂的ROWIDs,例如: Oracle數(shù)據(jù)庫(kù),如果你設(shè)置這個(gè)可選的rowid, Hibernate可以使用額外的字段rowid實(shí)現(xiàn)快速更新。ROWID是這個(gè)功能實(shí)現(xiàn)的重點(diǎn), 它代表了一個(gè)存儲(chǔ)元組(tuple)的物理位置。 (20subselect (可選: 它將一個(gè)不可變(immutable)并且只讀的實(shí)體映射到一個(gè)數(shù)據(jù)庫(kù)的 子查詢中。當(dāng)你想用視圖代替一張基本表的時(shí)候,這是有用的,但最好不要這樣做。更多的介紹請(qǐng)看下面內(nèi)容。 (21abstract (可選
17、: 用于在 的繼承結(jié)構(gòu) (hierarchies)中標(biāo)識(shí)抽象超類。 若指明的持久化類實(shí)際上是一個(gè)接口,這也是完全可以接受的。 之后你可以用元素 來(lái)指定該接口的實(shí)際實(shí)現(xiàn)類。 你可以持久化任何static(靜態(tài)的)內(nèi)部類。 你應(yīng)該使用標(biāo)準(zhǔn)的類名格式來(lái)指定類名,比如:Foo$Bar。 不可變類,mutable="false"不可以被應(yīng)用程序更新或者刪除。 這可以讓Hibernate做一些小小的性能優(yōu)化。 可選的proxy屬性允許延遲加載類的持久化實(shí)例。 Hibernate開始會(huì)返回實(shí)現(xiàn)了這個(gè)命名接口的CGLIB代理。當(dāng)代理的某個(gè)方法被實(shí)際調(diào)用的時(shí)候, 真實(shí)的持久化對(duì)象才會(huì)被裝載。
18、參見下面的“用于延遲裝載的代理”。 Implicit (隱式的多態(tài)是指,如果查詢時(shí)給出的是任何超類、該類實(shí)現(xiàn)的接口或者該類的 名字,都會(huì)返回這個(gè)類的實(shí)例;如果查詢中給出的是子類的名字,則會(huì)返回子類的實(shí)例。 Explicit (顯式)的多態(tài)是指,只有在查詢時(shí)給出明確的該類名字時(shí)才會(huì)返回這個(gè)類的實(shí)例; 同時(shí)只有在這個(gè) 的定義中作為 或者 出現(xiàn)的子類,才會(huì)可能返回。 在大多數(shù)情況下,默認(rèn)的polymorphism="implicit"都是合適的。 顯式的多態(tài)在有兩個(gè)不同的類映射到同一個(gè)表的時(shí)候很有用。(允許一個(gè)“輕型”的類,只包含部分表字段)。 persister屬性可以讓你定制
19、這個(gè)類使用的持久化策略。 你可以指定你自己實(shí)現(xiàn) 的子類,你甚至可以完全從頭開始編寫一個(gè) 接口的實(shí)現(xiàn), 比如是用儲(chǔ)存過(guò)程調(diào)用、序列化到文件或者LDAP數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)。 參閱,這是一個(gè)簡(jiǎn)單的例子 (“持久化”到一個(gè)Hashtable)。 請(qǐng)注意dynamic-update和dynamic-insert的設(shè)置并不會(huì)繼承到子類, 所以在 或者 元素中可能 需要再次設(shè)置。這些設(shè)置是否能夠提高效率要視情形而定。請(qǐng)用你的智慧決定是否使用。 使用select-before-update通常會(huì)降低性能。如果你重新連接一個(gè)脫管(detache)對(duì)象實(shí)例 到一個(gè)Session中時(shí),它可以防止數(shù)據(jù)庫(kù)不必要的觸發(fā)upda
20、te。 這就很有用了。 如果你打開了dynamic-update,你可以選擇幾種樂觀鎖定的策略: version(版本檢查) 檢查version/timestamp字段 all(全部) 檢查全部字段 dirty(臟檢查)只檢察修改過(guò)的字段 none(不檢查)不使用樂觀鎖定 我們非常強(qiáng)烈建議你在Hibernate中使用version/timestamp字段來(lái)進(jìn)行樂觀鎖定。 對(duì)性能來(lái)說(shuō),這是最好的選擇,并且這也是唯一能夠處理在session外進(jìn)行操作的策略(例如: 在使用Session.merge(的時(shí)候)。 對(duì)Hibernate映射來(lái)說(shuō)視圖和表是沒有區(qū)別的,這是因?yàn)樗鼈冊(cè)跀?shù)據(jù)層都是透明的( 注意
21、:一些數(shù)據(jù)庫(kù)不支持視圖屬性,特別是更新的時(shí)候)。有時(shí)你想使用視圖,但卻不能在數(shù)據(jù)庫(kù) 中創(chuàng)建它(例如:在遺留的schema中)。這樣的話,你可以映射一個(gè)不可變的(immutable)并且是 只讀的實(shí)體到一個(gè)給定的SQL子查詢表達(dá)式: select , max(bid.amount, count(*from itemjoin bid on bid.item_id = item.idgroup by .定義這個(gè)實(shí)體用到的表為同步(synchronize),確保自動(dòng)刷新(auto-flush)正確執(zhí)行, 并且依賴原實(shí)體的查詢不會(huì)返回過(guò)期數(shù)據(jù)。 在屬性元素 和一個(gè)嵌套
22、映射元素中都可見。 被映射的類必須定義對(duì)應(yīng)數(shù)據(jù)庫(kù)表主鍵字段。大多數(shù)類有一個(gè)JavaBeans風(fēng)格的屬性, 為每一個(gè)實(shí)例包含唯一的標(biāo)識(shí)。 元素定義了該屬性到數(shù)據(jù)庫(kù)表主鍵字段的映射。 name="propertyName" (1type="typename" (2column="column_name" (3unsaved-value="null|any|none|undefined|id_value" (4access="field|property|ClassName" (5node="
23、;element-name|attribute-name|element/attribute|.">(1name (可選: 標(biāo)識(shí)屬性的名字。 (2type (可選: 標(biāo)識(shí)Hibernate類型的名字。 (3column (可選 - 默認(rèn)為屬性名: 主鍵字段的名字。 (4unsaved-value (可選 - 默認(rèn)為一個(gè)切合實(shí)際(sensible)的值: 一個(gè)特定的標(biāo)識(shí)屬性值,用來(lái)標(biāo)志該實(shí)例是剛剛創(chuàng)建的,尚未保存。 這可以把這種實(shí)例和從以前的session中裝載過(guò)(可能又做過(guò)修改-譯者注) 但未再次持久化的實(shí)例區(qū)分開來(lái)。 (5access (可選 - 默認(rèn)為property: H
24、ibernate用來(lái)訪問屬性值的策略。 如果 name屬性不存在,會(huì)認(rèn)為這個(gè)類沒有標(biāo)識(shí)屬性。 unsaved-value 屬性在Hibernate3中幾乎不再需要。 還有一個(gè)另外的 定義可以訪問舊式的多主鍵數(shù)據(jù)。 我們強(qiáng)烈不建議使用這種方式。 可選的 子元素是一個(gè)Java類的名字, 用來(lái)為該持久化類的實(shí)例生成唯一的標(biāo)識(shí)。如果這個(gè)生成器實(shí)例需要某些配置值或者初始化參數(shù), 用元素來(lái)傳遞。 uid_tablenext_hi_value_column所有的生成器都實(shí)現(xiàn)接口。 這是一個(gè)非常簡(jiǎn)單的接口;某些應(yīng)用程序可以選擇提供他們自己特定的實(shí)現(xiàn)。當(dāng)然, Hibernate提供了很多內(nèi)置的實(shí)現(xiàn)。下面是一些內(nèi)
25、置生成器的快捷名字: increment 用于為long, short或者int類型生成 唯一標(biāo)識(shí)。只有在沒有其他進(jìn)程往同一張表中插入數(shù)據(jù)時(shí)才能使用。 在集群下不要使用。 identity 對(duì)DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的內(nèi)置標(biāo)識(shí)字段提供支持。 返回的標(biāo)識(shí)符是long, short 或者int類型的。 sequence 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence, 而在Interbase中使用生成器(generator。返回的標(biāo)識(shí)符是long, short或者 int類
26、型的。 hilo 使用一個(gè)高/低位算法高效的生成long, short 或者 int類型的標(biāo)識(shí)符。給定一個(gè)表和字段(默認(rèn)分別是 hibernate_unique_key 和next_hi)作為高位值的來(lái)源。 高/低位算法生成的標(biāo)識(shí)符只在一個(gè)特定的數(shù)據(jù)庫(kù)中是唯一的。 seqhilo 使用一個(gè)高/低位算法來(lái)高效的生成long, short 或者 int類型的標(biāo)識(shí)符,給定一個(gè)數(shù)據(jù)庫(kù)序列(sequence的名字。 uuid 用一個(gè)128-bit的UUID算法生成字符串類型的標(biāo)識(shí)符, 這在一個(gè)網(wǎng)絡(luò)中是唯一的(使用了IP地址)。UUID被編碼為一個(gè)32位16進(jìn)制數(shù)字的字符串。 guid 在MS SQL S
27、erver 和 MySQL 中使用數(shù)據(jù)庫(kù)生成的GUID字符串。 native 根據(jù)底層數(shù)據(jù)庫(kù)的能力選擇identity, sequence 或者h(yuǎn)ilo中的一個(gè)。 assigned 讓應(yīng)用程序在save(之前為對(duì)象分配一個(gè)標(biāo)示符。這是 元素沒有指定時(shí)的默認(rèn)生成策略。 select 通過(guò)數(shù)據(jù)庫(kù)觸發(fā)器選擇一些唯一主鍵的行并返回主鍵值來(lái)分配一個(gè)主鍵。 foreign 使用另外一個(gè)相關(guān)聯(lián)的對(duì)象的標(biāo)識(shí)符。通常和 聯(lián)合起來(lái)使用。 hilo 和 seqhilo生成器給出了兩種hi/lo算法的實(shí)現(xiàn), 這是一種很令人滿意的標(biāo)識(shí)符生成算法。第一種實(shí)現(xiàn)需要一個(gè)“特殊”的數(shù)據(jù)庫(kù)表來(lái)保存下一個(gè)可用的“hi”值。 第二種
28、實(shí)現(xiàn)使用一個(gè)Oracle風(fēng)格的序列(在被支持的情況下)。 hi_valuenext_value100hi_value100很不幸,你在為Hibernate自行提供Connection時(shí)無(wú)法使用hilo。 當(dāng)Hibernate使用JTA獲取應(yīng)用服務(wù)器的數(shù)據(jù)源連接時(shí),你必須正確地配置 。 UUID包含:IP地址,JVM的啟動(dòng)時(shí)間(精確到1/4秒),系統(tǒng)時(shí)間和一個(gè)計(jì)數(shù)器值(在JVM中唯一)。 在Java代碼中不可能獲得MAC地址或者內(nèi)存地址,所以這已經(jīng)是我們?cè)诓皇褂肑NI的前提下的能做的最好實(shí)現(xiàn)了。 對(duì)于內(nèi)部支持標(biāo)識(shí)字段的數(shù)據(jù)庫(kù)(DB2,MySQL,Sybase,MS SQL,你可以使用identi
29、ty關(guān)鍵字生成。 對(duì)于內(nèi)部支持序列的數(shù)據(jù)庫(kù)(DB2,Oracle, PostgreSQL, Interbase, McKoi,SAP DB, 你可以使用sequence風(fēng)格的關(guān)鍵字生成。 這兩種方式對(duì)于插入一個(gè)新的對(duì)象都需要兩次SQL查詢。 person_id_sequence對(duì)于跨平臺(tái)開發(fā),native策略會(huì)從identity, sequence 和hilo中進(jìn)行選擇,選擇哪一個(gè),這取決于底層數(shù)據(jù)庫(kù)的支持能力。 如果你需要應(yīng)用程序分配一個(gè)標(biāo)示符(而非Hibernate來(lái)生成),你可以使用assigned 生成器。這種特殊的生成器會(huì)使用已經(jīng)分配給對(duì)象的標(biāo)識(shí)符屬性的標(biāo)識(shí)符值。 這個(gè)生成器使用一個(gè)
30、自然鍵(natural key,有商業(yè)意義的列譯注)作為主鍵,而不是使用一個(gè)代理鍵( surrogate key,沒有商業(yè)意義的列譯注)。這是沒有指定 元素時(shí)的默認(rèn)行為 當(dāng)選擇assigned生成器時(shí),除非有一個(gè)version或timestamp屬性,或者你定義了 Interceptor.isUnsaved(,否則需要讓Hiberante使用 unsaved-value="undefined",強(qiáng)制Hibernatet查詢數(shù)據(jù)庫(kù)來(lái)確定一個(gè)實(shí)例是瞬時(shí)的(transient) 還是脫管的(detached)。 僅僅用于遺留的schema中 (Hibernate不能使用觸發(fā)器生成
31、DDL。 socialSecurityNumber在上面的例子中,類定義了一個(gè)命名為socialSecurityNumber的唯一值屬性, 它是一個(gè)自然鍵(natural key),命名為person_id的代理鍵(surrogate key) 的值由觸發(fā)器生成。 name="propertyName"class="ClassName"mapped="true|false"access="field|property|ClassName"node="element-name|.">.如果表
32、使用聯(lián)合主鍵,你可以映射類的多個(gè)屬性為標(biāo)識(shí)符屬性。 元素接受 屬性映射和 屬性映射作為子元素。 你的持久化類必須重載equals(和 hashCode(方法,來(lái)實(shí)現(xiàn)組合的標(biāo)識(shí)符的相等判斷。 實(shí)現(xiàn)Serializable接口也是必須的。 不幸的是,這種組合關(guān)鍵字的方法意味著一個(gè)持久化類是它自己的標(biāo)識(shí)。除了對(duì)象自己之外, 沒有什么方便的“把手”可用。你必須初始化持久化類的實(shí)例,填充它的標(biāo)識(shí)符屬性,再load( 組合關(guān)鍵字關(guān)聯(lián)的持久狀態(tài)。我們把這種方法稱為embedded(嵌入式)的組合標(biāo)識(shí)符,在重要的應(yīng)用中不鼓勵(lì)使用這種用法。 第二種方法我們稱為mapped(映射式組合標(biāo)識(shí)符 (mapped co
33、mposite identifier, 元素中列出的標(biāo)識(shí)屬性不但在持久化類出現(xiàn),還形成一個(gè)獨(dú)立的標(biāo)識(shí)符類。 在這個(gè)例子中,組合標(biāo)識(shí)符類MedicareId和實(shí)體類都含有medicareNumber和dependent屬性。標(biāo)識(shí)符類必須重載equals(和hashCode(并且實(shí)現(xiàn)Serializable接口。這種方法的缺點(diǎn)是出現(xiàn)了明顯的代碼重復(fù)。 下面列出的屬性是用來(lái)指定一個(gè)映射式組合標(biāo)識(shí)符的: mapped (可選, 默認(rèn)為false: 指明使用一個(gè)映射式組合標(biāo)識(shí)符,其包含的屬性映射同時(shí)在實(shí)體類和組合標(biāo)識(shí)符類中出現(xiàn)。 class (可選,但對(duì)映射式組合標(biāo)識(shí)符必須指定: 作為組合標(biāo)識(shí)符類使用的
34、類名. 在第 8.4 節(jié) “組件作為聯(lián)合標(biāo)識(shí)符(Components as composite identifiers”一節(jié)中,我們會(huì)描述第三種方式,那就是把組合標(biāo)識(shí)符實(shí)現(xiàn)為一個(gè)組件(component類,這是更方便的方法。下面的屬性僅對(duì)第三種方法有效: name (可選,但對(duì)這種方法而言必須: 包含此組件標(biāo)識(shí)符的組件類型的名字 (參閱第9章. access (可選 - 默認(rèn)為property: Hibernate應(yīng)該使用的訪問此屬性值的策略 class (可選 - 默認(rèn)會(huì)用反射來(lái)自動(dòng)判定屬性類型 : 用來(lái)作為組合標(biāo)識(shí)符的組件類的類名(參閱下一節(jié)) 第三種方式,被稱為ide
35、ntifier component(標(biāo)識(shí)符組件是我們對(duì)幾乎所有應(yīng)用都推薦使用的方式。 在"一棵對(duì)象繼承樹對(duì)應(yīng)一個(gè)表"的策略中, 元素是必需的, 它定義了表的鑒別器字段。鑒別器字段包含標(biāo)志值,用于告知持久化層應(yīng)該為某個(gè)特定的行創(chuàng)建哪一個(gè)子類的實(shí)例。 如下這些受到限制的類型可以使用: string, character, integer, byte, short, boolean, yes_no, true_false. column="discriminator_column" (1type="discriminator_type" (
36、2force="true|false" (3insert="true|false" (4formula="arbitrary sql expression" (5/>(1column (可選 - 默認(rèn)為 class 鑒別器字段的名字 (2type (可選 - 默認(rèn)為 string 一個(gè)Hibernate字段類型的名字 (3force(強(qiáng)制 (可選 - 默認(rèn)為 false "強(qiáng)制"Hibernate指定允許的鑒別器值,即使當(dāng)取得的所有實(shí)例都是根類的。 (4insert (可選 - 默認(rèn)為true 如果你的鑒別器
37、字段也是映射為復(fù)合標(biāo)識(shí)(composite identifier)的一部分,則需將 這個(gè)值設(shè)為false。(告訴Hibernate在做SQL INSERT 時(shí)不包含該列) (5formula (可選 一個(gè)SQL表達(dá)式,在類型判斷(判斷是父類還是具體子類譯注)時(shí)執(zhí)行??捎糜诨趦?nèi)容的鑒別器。 鑒別器字段的實(shí)際值是根據(jù) 和 元素中 的discriminator-value屬性得來(lái)的。 force屬性僅僅在這種情況下有用的:表中包含沒有被映射到持久化類的附加辨別器值。 這種情況不會(huì)經(jīng)常遇到。 使用formula屬性你可以定義一個(gè)SQL表達(dá)式,用來(lái)判斷一個(gè)行數(shù)據(jù)的類型。 formula="c
38、ase when CLASS_TYPE in ('a', 'b', 'c' then 0 else 1 end"type="integer"/>元素是可選的,表明表中包含附帶版本信息的數(shù)據(jù)。 這在你準(zhǔn)備使用 長(zhǎng)事務(wù)(long transactions)的時(shí)候特別有用。(見后) column="version_column" (1name="propertyName" (2type="typename" (3access="field|prop
39、erty|ClassName" (4unsaved-value="null|negative|undefined" (5generated="never|always" (6insert="true|false" (7node="element-name|attribute-name|element/attribute|."/>(1column (可選 - 默認(rèn)為屬性名: 指定持有版本號(hào)的字段名。 (2name: 持久化類的屬性名。 (3type (可選 - 默認(rèn)是 integer: 版本號(hào)的類型。
40、 (4access (可選 - 默認(rèn)是 property: Hibernate用于訪問屬性值的策略。 (5unsaved-value (可選 - 默認(rèn)是undefined: 用于標(biāo)明某個(gè)實(shí)例時(shí)剛剛被實(shí)例化的(尚未保存)版本屬性值,依靠這個(gè)值就可以把這種情況 和已經(jīng)在先前的session中保存或裝載的脫管(detached)實(shí)例區(qū)分開來(lái)。 (undefined指明應(yīng)被使用的標(biāo)識(shí)屬性值。) (6generated (可選 - 默認(rèn)是 never: 表明此版本屬性值是否實(shí)際上是由數(shù)據(jù)庫(kù)生成的。請(qǐng)參閱第 5.6 節(jié) “數(shù)據(jù)庫(kù)生成屬性(Generated Properties)”部分
41、的討論。 (7insert (可選 - 默認(rèn)是 true: 表明此版本列應(yīng)該包含在SQL插入語(yǔ)句中。只有當(dāng)數(shù)據(jù)庫(kù)字段有默認(rèn)值0的時(shí)候,才可以設(shè)置為false。 版本號(hào)必須是以下類型:long, integer, short, timestamp或者calendar。 一個(gè)脫管(detached)實(shí)例的version或timestamp屬性不能為空(null),因?yàn)镠ibernate不管 unsaved-value被指定為何種策略,它將任何屬性為空的version或timestamp 實(shí)例看作為瞬時(shí)(transient)實(shí)例。 避免Hibernate中的傳遞重附(transitive reatt
42、achment)問題的一個(gè)簡(jiǎn)單方法是 定義一個(gè)不能為空的version或timestamp屬性,特別是在人們使用程序分配的標(biāo)識(shí)符(assigned identifiers) 或復(fù)合主鍵時(shí)非常有用! 可選的 元素指明了表中包含時(shí)間戳數(shù)據(jù)。 這用來(lái)作為版本的替代。時(shí)間戳本質(zhì)上是一種對(duì)樂觀鎖定的一種不是特別安全的實(shí)現(xiàn)。當(dāng)然, 有時(shí)候應(yīng)用程序可能在其他方面使用時(shí)間戳。 column="timestamp_column" (1name="propertyName" (2access="field|property|ClassName" (3un
43、saved-value="null|undefined" (4source="vm|db" (5generated="never|always" (6node="element-name|attribute-name|element/attribute|."/>(1column (可選 - 默認(rèn)為屬性名: 持有時(shí)間戳的字段名。 (2name: 在持久化類中的JavaBeans風(fēng)格的屬性名, 其Java類型是 Date 或者 Timestamp的。 (3access (可選 - 默認(rèn)是 property: Hi
44、bernate用于訪問屬性值的策略。 (4unsaved-value (可選 - 默認(rèn)是null: 用于標(biāo)明某個(gè)實(shí)例時(shí)剛剛被實(shí)例化的(尚未保存)版本屬性值,依靠這個(gè)值就可以把這種情況和 已經(jīng)在先前的session中保存或裝載的脫管(detached)實(shí)例區(qū)分開來(lái)。(undefined 指明使用標(biāo)識(shí)屬性值進(jìn)行這種判斷。) (5source (可選 - 默認(rèn)是 vm: Hibernate如何才能獲取到時(shí)間戳的值呢?從數(shù)據(jù)庫(kù),還是當(dāng)前JVM?從數(shù)據(jù)庫(kù)獲取會(huì)帶來(lái)一些負(fù)擔(dān),因?yàn)镠ibernate必須訪問數(shù)據(jù)庫(kù)來(lái)獲得“下一個(gè)值”,但是在集群環(huán)境中會(huì)更安全些。還要注意,并不是所有的Dialect(方言)都支
45、持獲得數(shù)據(jù)庫(kù)的當(dāng)前時(shí)間戳的,而支持的數(shù)據(jù)庫(kù)中又有一部分因?yàn)榫炔蛔?用于鎖定是不安全的(例如Oracle 8)。 (6generated (可選 - 默認(rèn)是 never: 指出時(shí)間戳值是否實(shí)際上是由數(shù)據(jù)庫(kù)生成的.請(qǐng)參閱第 5.6 節(jié) “數(shù)據(jù)庫(kù)生成屬性(Generated Properties)”的討論。 注意, 和 是等價(jià)的。并且 和 是等價(jià)的。 元素為類定義了一個(gè)持久化的,JavaBean風(fēng)格的屬性。 name="propertyName" (1column="column_name" (2type="typename&q
46、uot; (3update="true|false" (4insert="true|false" (4formula="arbitrary SQL expression" (5access="field|property|ClassName" (6lazy="true|false" (7unique="true|false" (8not-null="true|false" (9optimistic-lock="true|false" (
47、10generated="never|insert|always" (11node="element-name|attribute-name|element/attribute|."index="index_name"unique_key="unique_key_id"length="L"precision="P"scale="S"/>(1name: 屬性的名字,以小寫字母開頭。 (2column (可選 - 默認(rèn)為屬性名字: 對(duì)應(yīng)的數(shù)據(jù)庫(kù)字段名。
48、也可以通過(guò)嵌套的 元素指定。 (3type (可選: 一個(gè)Hibernate類型的名字。 (4update, insert (可選 - 默認(rèn)為 true : 表明用于UPDATE 和/或 INSERT 的SQL語(yǔ)句中是否包含這個(gè)被映射了的字段。這二者如果都設(shè)置為false 則表明這是一個(gè)“外源性(derived)”的屬性,它的值來(lái)源于映射到同一個(gè)(或多個(gè)) 字段的某些其他屬性,或者通過(guò)一個(gè)trigger(觸發(fā)器)或其他程序生成。 (5formula (可選: 一個(gè)SQL表達(dá)式,定義了這個(gè)計(jì)算 (computed) 屬性的值。計(jì)算屬性沒有和它對(duì)應(yīng)的數(shù)據(jù)庫(kù)字段。 (6access (可選 - 默認(rèn)
49、值為 property: Hibernate用來(lái)訪問屬性值的策略。 (7lazy (可選 - 默認(rèn)為 false: 指定 指定實(shí)例變量第一次被訪問時(shí),這個(gè)屬性是否延遲抓取(fetched lazily)( 需要運(yùn)行時(shí)字節(jié)碼增強(qiáng))。 (8unique (可選: 使用DDL為該字段添加唯一的約束。 同樣,允許它作為property-ref引用的目標(biāo)。 (9not-null (可選: 使用DDL為該字段添加可否為空(nullability)的約束。 (10optimistic-lock (可選 - 默認(rèn)為 true: 指定這個(gè)屬性在做更新時(shí)是否需要獲得樂觀鎖定(optimistic lock)。 換
50、句話說(shuō),它決定這個(gè)屬性發(fā)生臟數(shù)據(jù)時(shí)版本(version)的值是否增長(zhǎng)。 (11generated (可選 - 默認(rèn)為 never: 表明此屬性值是否實(shí)際上是由數(shù)據(jù)庫(kù)生成的。請(qǐng)參閱第 5.6 節(jié) “數(shù)據(jù)庫(kù)生成屬性(Generated Properties)”的討論。 typename可以是如下幾種: Hibernate基本類型名(比如:integer, string, character,date, timestamp, float, binary, serializable, object, blob)。 一個(gè)Java類的名字,這個(gè)類屬于一種默認(rèn)基礎(chǔ)類型 (比如: 。 一個(gè)
51、可以序列化的Java類的名字。 一個(gè)自定義類型的類的名字。(比如: 。 如果你沒有指定類型,Hibernarte會(huì)使用反射來(lái)得到這個(gè)名字的屬性,以此來(lái)猜測(cè)正確的Hibernate類型。 Hibernate會(huì)按照規(guī)則2,3,4的順序?qū)傩宰x取器(getter方法)的返回類進(jìn)行解釋。然而,這還不夠。 在某些情況下你仍然需要type屬性。(比如,為了區(qū)別Hibernate.DATE 和Hibernate.TIMESTAMP,或者為了指定一個(gè)自定義類型。) access屬性用來(lái)讓你控制Hibernate如何在運(yùn)行時(shí)訪問屬性。在默認(rèn)情況下, Hibernate會(huì)使用屬性的get/set方法對(duì)(pair)
52、。如果你指明access="field", Hibernate會(huì)忽略get/set方法對(duì),直接使用反射來(lái)訪問成員變量。你也可以指定你自己的策略, 這就需要你自己實(shí)現(xiàn)接口, 再在access中設(shè)置你自定義策略類的名字。 衍生屬性(derive propertie)是一個(gè)特別強(qiáng)大的特征。這些屬性應(yīng)該定義為只讀,屬性值在裝載時(shí)計(jì)算生成。 你用一個(gè)SQL表達(dá)式生成計(jì)算的結(jié)果,它會(huì)在這個(gè)實(shí)例轉(zhuǎn)載時(shí)翻譯成一個(gè)SQL查詢的SELECT 子查詢語(yǔ)句。 WHERE ductId = ductIdAND li.customerId = customerIdAND li.o
53、rderNumber = orderNumber "/>注意,你可以使用實(shí)體自己的表,而不用為這個(gè)特別的列定義別名( 上面例子中的customerId)。同時(shí)注意,如果你不喜歡使用屬性, 你可以使用嵌套的 映射元素。 通過(guò)many-to-one元素,可以定義一種常見的與另一個(gè)持久化類的關(guān)聯(lián)。 這種關(guān)系模型是多對(duì)一關(guān)聯(lián)(實(shí)際上是一個(gè)對(duì)象引用譯注):這個(gè)表的一個(gè)外鍵引用目標(biāo)表的 主鍵字段。 name="propertyName" (1column="column_name" (2class="ClassName" (3ca
54、scade="cascade_style" (4fetch="join|select" (5update="true|false" (6insert="true|false" (6property-ref="propertyNameFromAssociatedClass" (7access="field|property|ClassName" (8unique="true|false" (9not-null="true|false" (
55、10optimistic-lock="true|false" (11lazy="proxy|no-proxy|false" (12not-found="ignore|exception" (13entity-name="EntityName" (14formula="arbitrary SQL expression" (15node="element-name|attribute-name|element/attribute|."embed-xml="true|fa
56、lse"index="index_name"unique_key="unique_key_id"foreign-key="foreign_key_name"/>(1name: 屬性名。 (2column (可選: 外間字段名。它也可以通過(guò)嵌套的 元素指定。 (3class (可選 - 默認(rèn)是通過(guò)反射得到屬性類型: 關(guān)聯(lián)的類的名字。 (4cascade(級(jí)聯(lián)) (可選: 指明哪些操作會(huì)從父對(duì)象級(jí)聯(lián)到關(guān)聯(lián)的對(duì)象。 (5fetch (可選 - 默認(rèn)為 select: 在外連接抓取(outer-join fetching)和序
57、列選擇抓取(sequential select fetching)兩者中選擇其一。 (6update, insert (可選 - 默認(rèn)為 true 指定對(duì)應(yīng)的字段是否包含在用于UPDATE 和/或 INSERT 的SQL語(yǔ)句中。如果二者都是false,則這是一個(gè)純粹的 “外源性(derived)”關(guān)聯(lián),它的值是通過(guò)映射到同一個(gè)(或多個(gè))字段的某些其他屬性得到 或者通過(guò)trigger(觸發(fā)器)、或其他程序生成。 (6property-ref: (可選 指定關(guān)聯(lián)類的一個(gè)屬性,這個(gè)屬性將會(huì)和本外鍵相對(duì)應(yīng)。 如果沒有指定,會(huì)使用對(duì)方關(guān)聯(lián)類的主鍵。 (7access (可選 - 默認(rèn)是 property
58、: Hibernate用來(lái)訪問屬性的策略。 (8unique (可選: 使用DDL為外鍵字段生成一個(gè)唯一約束。此外, 這也可以用作property-ref的目標(biāo)屬性。這使關(guān)聯(lián)同時(shí)具有 一對(duì)一的效果。 (9not-null (可選: 使用DDL為外鍵字段生成一個(gè)非空約束。 (10optimistic-lock (可選 - 默認(rèn)為 true: 指定這個(gè)屬性在做更新時(shí)是否需要獲得樂觀鎖定(optimistic lock)。 換句話說(shuō),它決定這個(gè)屬性發(fā)生臟數(shù)據(jù)時(shí)版本(version)的值是否增長(zhǎng)。 (11lazy (可選 - 默認(rèn)為 proxy: 默認(rèn)情況下,單點(diǎn)關(guān)聯(lián)是經(jīng)過(guò)代理的。lazy="
59、;no-proxy"指定此屬性應(yīng)該在實(shí)例變量第一次被訪問時(shí)應(yīng)該延遲抓取(fetche lazily)(需要運(yùn)行時(shí)字節(jié)碼的增強(qiáng))。 lazy="false"指定此關(guān)聯(lián)總是被預(yù)先抓取。 (12not-found (可選 - 默認(rèn)為 exception: 指定外鍵引用的數(shù)據(jù)不存在時(shí)如何處理: ignore會(huì)將行數(shù)據(jù)不存在視為一個(gè)空(null)關(guān)聯(lián)。 (13entity-name (可選: 被關(guān)聯(lián)的類的實(shí)體名。 (14formula (可選: SQL表達(dá)式,用于定義computed(計(jì)算出的)外鍵值。 cascade屬性設(shè)置為除了none以外任何有意義的值, 它將把特定的
60、操作傳遞到關(guān)聯(lián)對(duì)象中。這個(gè)值就代表著Hibernate基本操作的名稱, persist, merge, delete, save-update, evict, replicate, lock, refresh, 以及特別的值delete-orphan和all,并且可以用逗號(hào)分隔符 來(lái)組合這些操作,例如,cascade="persist,merge,evict"或 cascade="all,delete-orphan"。更全面的解釋請(qǐng)參考第 10.11 節(jié) “傳播性持久化(transitive persistence”. 注意,單值關(guān)聯(lián)
61、 (many-to-one 和 one-to-one 關(guān)聯(lián) 不支持刪除孤兒(orphan delete,刪除不再被引用的值). 一個(gè)典型的簡(jiǎn)單many-to-one定義例子: property-ref屬性只應(yīng)該用來(lái)對(duì)付遺留下來(lái)的數(shù)據(jù)庫(kù)系統(tǒng), 可能有外鍵指向?qū)Ψ疥P(guān)聯(lián)表的是個(gè)非主鍵字段(但是應(yīng)該是一個(gè)惟一關(guān)鍵字)的情況下。 這是一種十分丑陋的關(guān)系模型。比如說(shuō),假設(shè)Product類有一個(gè)惟一的序列號(hào), 它并不是主鍵。(unique屬性控制Hibernate通過(guò)SchemaExport工具進(jìn)行的DDL生成。) 那么關(guān)于OrderItem 的映射可能是: 當(dāng)然,我們決不鼓勵(lì)這種用法。 如果被引用的唯一主鍵由關(guān)聯(lián)實(shí)體的多個(gè)屬性組成,你應(yīng)該在名稱為 的元素 里面映射所有關(guān)聯(lián)的屬性。 假若被引用的唯一主鍵是組件的屬性,你可以指定屬性路徑: 持久化對(duì)象之間一對(duì)一的關(guān)聯(lián)關(guān)系是通過(guò)one-to-one元素定義的。 name="propertyName" (1class="ClassName" (2cascade="cascade_style" (3constrained="true|false" (4fetch="join|select" (5property-ref="
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 潔廁劑品牌如何利用短視頻平臺(tái)進(jìn)行推廣
- 2025年度針對(duì)高技能人才優(yōu)化薪酬體系勞動(dòng)合同
- 試用期協(xié)議-2025年度企業(yè)新員工試用期權(quán)益保障合同
- 2025年度新能源發(fā)電項(xiàng)目產(chǎn)權(quán)轉(zhuǎn)讓合同
- 二零二五年度兒童教育產(chǎn)品營(yíng)銷策劃合同
- 2025年度知識(shí)產(chǎn)權(quán)許可合同審查與交易安全指引
- 二零二五年度廚師個(gè)人與餐飲品牌老板合作開發(fā)合同
- 2025年度海參干貨行業(yè)論壇組織與贊助合同
- 二零二五年度房屋買賣合同解除后的合同解除條件協(xié)議
- 2025年度環(huán)保材料產(chǎn)品設(shè)計(jì)及市場(chǎng)推廣合同
- 高級(jí)財(cái)務(wù)會(huì)計(jì)-第7版全書教案
- 電動(dòng)葫蘆安全檢查表
- 考察領(lǐng)導(dǎo)談話怎么評(píng)價(jià)領(lǐng)導(dǎo)【六篇】
- 無(wú)側(cè)限抗壓強(qiáng)度試驗(yàn)記錄
- 鉗形電流表使用PPT
- 建筑工程分部分項(xiàng)工程劃分表(新版)
- 福建省危險(xiǎn)化學(xué)品企業(yè)安全標(biāo)準(zhǔn)化(三級(jí))考核評(píng)分標(biāo)準(zhǔn)指導(dǎo)意見(試行)
- 上海市長(zhǎng)寧區(qū)2022年高考英語(yǔ)一模試卷(含答案)
- 城鎮(zhèn)詳細(xì)設(shè)計(jì)控制性詳細(xì)規(guī)劃
- 智能垃圾桶系統(tǒng)的設(shè)計(jì)論文
- 質(zhì)量管理體系過(guò)程識(shí)別矩陣圖及與條款對(duì)照表
評(píng)論
0/150
提交評(píng)論