JDO元数据介绍
作者语:JDO中的meta data是JDO一个关键的内容,就像EJB中的ejb-jar.xml,我写这篇文章完全是出于查阅的方便,因为大多数JDO工具或者向导都可以根据你的持久化对象自动生成相应的JDO metadata,不过为了便于你学习和理解它们的含义,我还是把它放到这里希望对大家学习JDO有所帮助。
在JDO中,每一个可持持久化类都有一个相应的元数据文件,这个元数据文件的作用体现在3个方面:
1、 维护持久化类的一致性
2、 重载缺省的持久化行为
3、 为JDO实现提供持久化类本身无法提供的附加信息。
JDO元数据文件是XML格式的文件。这个文件的根元素必须是jdo,另外他有一个唯一的必须的子元素package元素,package元素代表持久化类所在的包,他有一个name属性,这个属性的值代表package的完整名称。下面我给出一个最基本的jdo元数据的例子:
<?xml version=”1.0”?>
<jdo>
<package name=”com.lgd.test”>
…………….
</package>
<package name=”org.lgd.test”>
…………….
</package>
</jdo>
package元素可以包含1-n个class元素,还可以有0-n个扩展元素,这些扩展元素通常提供特定的JDO厂商实现的信息。扩展元素一般是extension元素,他有3个属性:
vender-name:厂商的名称,必须有的属性。
Key:扩展属性的名称,每个JDO实现厂商都会提供一系列的属性名。
Value:扩展属性的值
Package中的每个类的描述用class元素,calss元素需要一个name属性来描述他的名称,name属性的写法一般遵循以下价格原则:
l 如果这个clss元素包含在package元素中,那么他的name可以直接写类名就可以了,不用包含包名,比如com.lgd.test.HelloWorld这个类他的name直接写HellpWorld就可以了。
l 同样的对于java.lang,java.util,java.math中的类也可以直接写他的类名。
l 除了上面两种情况,类的name必须是完整的名称,要包含具体的包路径。
l 如果所描述的类是一个内部类,那么他的写法是这样的,parent-calss$inner-class.比如:Human$Man。
下面让我们来看看class具体有那些属性:
l name:类的名称,必须的属性。
l persistence-capable-supperclass:如果这个类的超类也是一个可持久化的类,并且你希望JDO实现明白他们直接的继承关系,你就要在这里指定。
l identity-type:它指定了持久化类的一致性类型,如果你定义了objectid-class那么这个属性默认为application否则就是datastore.
l objectid-class:对于应用程序JDO一致性的持久化类要指定他的JDO一致性类,这个类位于继承树的最底层的类。
l requires-extent:如果你不从这个类中查询数据,那么可以把它设置为false,缺省情况下是true.
下面给出一个有关class元素的例子:
<?xml version="1.0"?>
<jdo>
<package name="com.lgd.test">
<class name="Human" objectid-class="Human$ObjectId">
...
</class>
<class name="African">
...
</class>
<class name="Asian" persistence-capable-superclass="Human">
...
</class>
<class name="Asian$Chinese">
...
</class>
</package>
</jdo>
class元素还包含extension和field子元素。我们先来看看field元素。它用来描述持久化类中的字段。这个字段是一个可选字段,如果你不在元数据文件中用field字段来描述, JDO会使用缺省的描述每一个字段,这样一来就给我们省去了很多工作。让我们来看看filed元素都有那些属性:
l name:字段的名称,要和你在持久化类中的字段名称一致。
l persistence-modifier:定义JDO如何操作这个字段,如果是可持久字段值为:persistent。如果是非持久字段但是可以被回滚的字段,值为transactional。如果都不是,那么值为none。这些字段的缺省要根据字段的类型而定:
m 如果字段被声明为fianl,transient或static那么他的缺省值为:none.
m 如果字段类型为原始类型或原始类型的封装类型,那么他的缺省值为:pesistent
m 如果字段类型为java.util.Date,java.util.Locale,java.lang.String,java.lang.Number, java.math.BigDecimail或java.math.BigInteger那么缺省值为:persistent
m 如果字段类型为用户定义的可持久类型那么缺省值为:persistent
m 我们前面说过的数组类型的字段缺省值为:persistent
m 字段类型如果是java.util包中的以下类型缺省为persistent.: Collection, Set, List, Map, ArrayList, HashMap, HashSet, Hashtable, LinkedList, TreeMap, TreeSet, Vector
m 其他的类型缺省为none
l primary-key:如果这个字段是主键字段就把它设置为true,缺省为false。
l none-value:缺省设置为none代表设置一个空值到数据库中。
l default-fetch-group:原始类型和原始封装类型缺省为true其他类型设置为false。
l embedded: 原始类型和原始封装类型缺省为true其他类型设置为false。
所有的元素都可能会有一个extension的扩展元素,数组(array)元素和集合(collection)元素会有一个embedded-element属性,它定义了元素或数组的内部元素的类型(embedded-type)。
l key-type:对象用于映射的键,缺省为java.lang.Object
l embedded-key:内嵌的键
l value-type:键的值
l embedded-value:内嵌的键值
下面给出一个包含所有元数据文件元素的例子:
<?xml version="1.0"?>
<jdo>
<package name="org.lgd.test">
<class name="Human" objectid-class="Human$ObjectId">
<field name="ID" primary-key="true"/>
<field name="name" primary-key="true"/>
<field name="dress">
<collection element-type="Dress"/>
</field>
</class>
<class name="Dress">
<field name="color">
<map key-type="String" value-type="ColorTye"/>
</field>
</class>
<class name="ColorTye">
<field name="red" embedded="true"/>
<field name="blue" embedded="true"/>
</class>
</package>
<package name="org.lgd.test">
<class name="Human"/>
<class name="Asian" persistence-capable-superclass="Human">
<field name="country">
<collection element-type="Asua$Chinese"/>
<extension vendor-name="kodo" key="inverse-owner" value="Human"/>
</field>
</class>
<class name="Human$Asian"/>
</package>
</jdo>
JDO文件的位置:
JDO元数据文件是一个资源文件,在类增强和运行时都会使用到它,如果这个元数据是对一个类的描述,那么他的名称就是类的名称,它与类文件放在同一个目录下。如果JDO元数据文件包含一个包下面的所有类的描述那么它就放在相应的包所在的路径下,也可以是整个包层次中所有的类的描述,比如:对于Human.class的元数据描述文件可以是Human.jdo或者把它包含在一个package.jdo中,那么这个文件的位置可以是:
com/lgd/test/Human.jdo
com/lgd/package.jdo
com/package.jdo
package.jdo
由于JDO元数据文件是一个资源文件,所以它也可以放到.jar文件中被访问。
结束
以上就是有关JDO元数据的介绍,这些内容都是符合JDO1.0规范的内容,由于不同JDO实现厂商对于JDO元数据还有相应的扩展或需要其他的支持(比如 Kodo JDO还需要额外的一个maping文件与之对应)所以在使用具体的实现是可以参考厂商自带的文档。