第五章 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文件中读取它。