第五章 JDO元數據
JDO要求每個持久類都必須有元數據.元數據有三個基本作用:
1)標識持久類
2)重載默認JDO行爲
3)告訴JDO持久類的內省信息
元數據是一個XML文檔,下節會討論它的DTD.無須強求自己立即明白DTD,下節我們會全面介紹它.
JDO元素是元數據文檔的根元素.它只有一個子元素.package.每個package元素都必須用包的全稱來指定名字屬性
package元素包含一個或多個class元素.子元素後面可以有0個或者多個擴展元素.擴展元素的作用是用廠商指定的信息來解釋元數據.擴展元素還可以包含擴展子元素.它有三個屬性:
廠商名稱:擴展元素應用於哪個廠商.必須提供.
關鍵字:你所設置的擴展屬性的名稱.每個廠商都會提供所支持屬性的列表.
值:屬性的值
每個在package元素裏的持久類都必須有class元素,在詳細解釋它之前,先簡單瞭解JDO如何解析類的名字
一些元數據屬性要求你指定類名.類名必須遵守以下準則:
1)如果類所在的包就是當前包元素,那麼只需給出類名.不用指定包名.例如,如果當前包名是org.mag,類名是org.mag.Magazine,那麼類名只寫Magazine
2)否則,必須給出包括包的類名.
3)如果類是內嵌類,必須寫成父類$內嵌類的形式.如 SubscriptionForm$LineItem
現在繼續介紹class元素.這個元素有以下屬性:
name:類名,必需屬性
persistence-capable-superclass:如果父類也是持久化的,而你希望JDO能知道這個繼承層次,那麼你必須在這個屬性裏指定父類.如果父類是非持久化的,你不應該使用這個屬性
identity-type:給出類所使用的JDO標識.application表示使用應用程序標識, datastore 表示使用數據存儲標識,none表示沒有使用.如果指定了objectid-class屬性,那麼默認值爲application.否則爲datastore
objectid-class:爲應用程序標識而使用.屬性值爲JDO標識類的值.注意只需給出基類的值
requires-extent:如果你不查詢這個類的持久化實例,那麼屬性值爲false.(例如,這個類的所有對象都可以通過JDO標識查找而得或通過其他對象的關係得到)默認爲true
class元素可以包含extension元素和field元素.field元素反映了能持久類聲明的字段,這些元素是可選的.如果類聲明的字段沒有在field元素中給出,它的值由下面列出的屬性來給出.感謝JDO善解人意的默認設置,許多字段不必顯式的列出.field元素有以下屬性:
name:字段名.持久類聲明的字段名稱.必需.
persistence-modifier: 指定JDO如何管理字段.這種做法是合理的,如果是持久化字段,則設爲persistent,如果是事務性的就設爲 non-persistent.和none.默認值由字段的類型來決定.
1)聲明爲static,transient,final的爲none
2)任何基本類型和基本類型包裝爲persistent
3)java.lang.String,java.lang.Number,java.math.BigDecimal,java.math.BigInteger, ava.util.Locale和java.util.Date default爲persistent
4)字段類型爲自定義的能持久類爲persistent
5)上述類型的數組也爲persistent
6)java.util包裏的集合類,如List,Map,Set,Collection,HashSet等都爲persistent
7)其他都爲none
primary-key: 如果類使用應用程序標識且該字段爲主鍵字段,設爲true,否則爲false
null-value:指定如果值爲null時,將字段寫到數據存儲的操作.如果這個字段的值存儲爲null,則設none.如果想存儲一個數據庫的默認值,設爲default,最後,如果該字段將要寫入到數據存儲時它的值爲null,而你想拋出一個異常.那麼這裏你應該設爲exception.默認爲none
default-fetch-group:默認取出組的字段作爲組來管理.這樣可以提高效率.例如從數據庫中讀取一批數據,把一批數據寫入數據庫.如果字段類型是基本類型,基本類型包裝,字符串,日期,BigDecimal和BigInteger,則屬性值爲true.其他類型默認爲false.(注意默認爲false並不表示就是false)
embedded:該屬性提示JDO把該字段作爲類實例的一部分存儲到數據庫.而不是作爲單獨的實體而保存.如果類型是基本類型,基本類型包裝類,日期,BigDecimal和BigInteger,數組,集合和map類型,則默認值爲true.其他類型默認爲false.嵌入的對象不能在類的Extent出現,並且不能被查詢取得.
所有field元素應該包含extension子元素 , 字段如果是數組,集合或者map有可能再包含一個數組,集合或者map子元素.分別地,每個這樣的子元素會分別包含額外的extension元素
array元素只有一個屬性.embedded-element,這個屬性映射class元素的attribute屬性,應用於每個數組索引.
collection 元素也有.embedded-element 屬性.還有element-type 屬性.這個屬性告訴JDO這個collection 含有什麼.默認爲包含object
msp元素定義四個屬性,他們是:
1)key-type:map的key的類型.默認爲object
2)embedded-key:和集合的屬性相似.應用於所有map key
3)value-type:map的值的類型,默認爲object
4)embedded-value:和embedded-key類似,應用於所有map的value
這裏已經列出了元數據的文檔結構.下面提供了一個完整的例子:
5.2. 元數據定位
org/mag/Magazine.jdo
org/mag/package.jdo
org/package.jdo
package.jdo
在增強類和運行時都需要元數據。元數據文檔必須作爲資源供類裝載器裝載。必須放置在以下位置:
1)取名爲類名.jdo的資源文件。類名指的是元數據將要在其上起作用的類。這個資源文件必須和類放在同一個包下。
2)取名爲包名.jdo。這個資源文件必須和相應的包一起存放,或者任何祖輩的包。包層次的文檔必須含有包括所有可持久化類的元數據,除了那些有自己的類名.jdo的類。他們也可能在子包包含類的元數據。
假設你使用標準的類裝載器,有一個類Magazine定義在文件org/mag/Magazine.class 裏,那麼相應的元數據文檔應該在下面任一文件加以定義:
1)org/mag/Magazine.jdo
2)org/mag/package.jdo
3)org/package.jdo
4)package.jdo
由於元數據作爲資源裝載,所以JDO頁可以從far文件中讀取它。