Castor功能与应用参考(五)- JDO映射定义

索引
1. JDO映射概述
我们在本前文中对Castor XML映射进行了详细的描述,并对Castor JDO做了一个概括介绍。Castor JDO在为XML文档与Java对象之间建立映射的同时,也提供了Java对象与关系数据库之间的映射机制,通常称为O/R映射。Castor映射文件可以同时为XML文档与Java对象,数据库关系表与Java对象之间提供映射信息。本文将对Castor O/R映射定义给出详细的描述。
下面是Castor O/R映射定义的例子:
< mapping xmlns =" http://castor.exolab.org/ ">
< description > Castor generated mapping file </ description >
< class name =" ZB_JG_SJB " identity =" NUM_ID ">
< description > Default mapping for class ZB_JG_SJB </ description >
< map-to table =" ZB_JG_SJB "/>
< field name =" NUM_ID " type =" int " required =" true ">
< sql name =" NUM_ID " type =" decimal " dirty =" check "/>
</ field >
< field name =" time " type =" java.util.Date " required =" true ">
< sql name =" time " type =" timestamp " dirty =" check "/>
</ field >
< field name =" unirow " type =" java.lang.String " required =" true ">
< sql name =" unirow " type =" varchar " dirty =" check "/>
</ field >
< field name =" status " type =" java.lang.String " required =" true ">
< sql name =" status " type =" varchar " dirty =" check "/>
</ field >
< field name =" insert_Date " type =" java.util.Date " required =" true ">
< sql name =" insert_Date " type =" timestamp " dirty =" check "/>
</ field >
</ class >
</mapping>
与Castor XML映射定义类似,一个Java类(<class>节点)通过<map-to>节点的“table”属性映射为一张数据库表(上例为 < map-to table =" ZB_JG_SJB "/>)。Java类字段(<field>节点)映射为数据库表中的列(通过<sql>节点表示)。
本文将不给出Mapping映射文件中各节点的Schema定义,关于其定义参考前文或Castor映射定义Schema文档。
2. 映射定义详解
2.1Mapping文件的根节点
如上例Mapping 文件所示,Mapping 文件的根节点为 <mapping><mapping>节点下的节点包括:
ü一个 < description > 节点,可选的,用于添加描述信息
ü一个或多个 < include > 节点,用于引用其他的映射文件
ü一个或多个 < class > 节点,用于描述每一个定义 Mapping Java
ü一个或多个 < key-generator > 节点,该节点在 Castor JDO 中用于自动生成记录的主键。我们将在下文中对其做详细解释。
2.2<class>节点定义
< class > 节点包含了 Java 类与数据库关系表之间映射的所有信息。该节点及其子节点详细描述了 Java 类中各个字段属性与数据库表列信息的映射关系。
2.2.1 <class>节点的属性
Øname: 映射的Java 类名称,使用类的全名,如”com.acme.MyClass” 。
Øextends: 只有在该类扩展其他类时,使用该参数指定扩展的类。如果被扩展的类未在该Mapping 文件中指定,则不能使用该属性。
Ødepends: 在Castor JDO 中指明类之间的依赖关系,用于表示数据库表中关联表的概念。关于关联关系参考下一节 关联关系
Øauto-complete: 如果该属性值为”true” ,则Castor 在处理该类时首先采用自省的方式决定该类的字段属性,然后使用Mapping 文件中对该字段属性的设定覆盖自省方式的操作。auto-complete 属性可以让Castor 的默认自省处理方式与Mapping 定义方式很好的结合,从而降低对包含很多字段的类进行复杂的设定操作。
Øidentity: 在Castor JDO 中使用,用于描述该类实例的主键字段,详细信息参考Castor JDO 部分。
Øaccess: 在Castor JDO 中使用,详细信息参考Castor JDO 部分。
Økey-generator: 在Castor JDO 中使用,详细信息参考Castor JDO 部分。
2.2.2 <class>节点的子节点
Ødescription 可选的属性,用于对该类添加描述性信息
Øcache-type: 只在Castor JDO 中使用,详细信息参考Castor JDO 部分。
Ømap-to: 可选属性,如果XML 中节点名称与类(Class) 名称不同,则使用该节点设定。默认的,Castor 会自动分析XML 节点名称和类名称之间的映射,如对于Java 类”XxxYyy” ,Castor 会自动映射为XML 节点”xxx-yyy” 。如果用户不希望Castor 自动生成该名称,则可以使用<map-to> 节点来指定XML 映射名称。注意:<map-to> 仅用于XML文档中的根节点。
Øfield 节点下包含 零个或多个<field>节点。每个<field>节点用于描述Java类中的一个字段属性。<class>
<class> 映射举例
下面的例子将Java 类MyClass 映射为数据库TestData 表:
package mypackage
public class MyClass {
 public int foo;
 public String getBar() { ... }
 public void setBar(String bar) { ... }
}
TestData表结构如下
CREATE TABLE TestData (
‘ID’ int(10) unsigned NOT NULL default '0',
‘Bar’ varchar(45) default NULL,
);
用户需要以如下方式设定Mapping映射文件:
 <mapping>
 ...
 <class name="mypackage.MyClass">
 <map-to table="TestData"/>
 <field name="foo" type=”int” direct="true" ...>
 <sql name="ID" type="int"/>
 </field>
 </field name="bar" type=”string”>
 <sql name="Bar" type="char"/>
 </field>
 </class>
 ...
</mapping>
2.3<map-to>节点定义
<map-to> 节点用于指定给定Java 类与数据库表名称的映射。
Øtable 属性:该Java 类所映射的关系数据库表的名称。
2.4< field>节点定义
<field> 节点用于描述如何编组/ 解编Java 对象中的字段属性。Castor 可以从<field> 节点描述中的”name” 属性确定Java 字段的名称;可以从<field> 节点描述中的”type” 和”collection” 属性确定Java 字段的类型;可以从<field> 节点描述中的”direct” ,”get-method” 和”set-method” 属性确定Java 字段的访问方法。通过上述信息,Castor 能够操作Java 类中的字段属性。
Castor 通过以下两个规则来判定某一字段的类型签名:
u检查 <field>节点中的“类型”属性(”type””collection”
如果 <field> 节点中没有 ”collection” 属性, ”type” 属性指定的类型即为该字段的 Java 类型。 ”type” 属性值既可以是 Java 对象类型的全限定名 ( 包含包名称 ) ,也可以是 Castor 定义的一系列简称。 Castor 支持的类型别名及对应的原始 Java 类型列表如下:
简称
原始类型
Java类型
big-decimal
N
java.math.BigDecimal
big-integer
Y
java.math.BigInteger
boolean
Y
java.lang.Boolean.TYPE
byte
Y
java.lang.Byte.TYPE
bytes
N
byte[]
char
Y
java.lang.Character.TYPE
chars
N
char[]
clob
N
java.sql.Clob
date
N
java.util.Date
double
Y
java.lang.Double.TYPE
float
Y
java.lang.Float.TYPE
int
Y
java.lang.Integer.TYPE
integer
Y
java.lang.Integer
locale
N
java.util.Locale
long
Y
java.lang.Long.TYPE
other
N
java.lang.Object
serializable
Y
java.io.Serializable
short
Y
java.lang.Short.TYPE
sqldate
Y
java.sql.Date
sqltime
Y
java.sql.Date
string
N
java.lang.String
strings
N
String[]
stream
N
java.io.InputStream
timestamp
N
java.sql.Timestamp
Castor 会自动将数据库表中的数据转换为上述Java 对象类型。如果设定了”collection”属性,collection属性值遵从下面的对象对象列表:
简称
原始类型
Java 类型
array
<type_attribute>[]
<type_attribute>[]
enumerate
java.util.Enumeration
-
collection
java.util.Collection
java.util.ArrayList
set
java.util.Set
java.util.HashSet
arraylist
java.util.ArrayList
java.util.ArrayList
vector
java.util.Vector
java.util.Vector
map
java.util.Map
java.util.HashMap
hashtable
java.util.Hashtable
java.util.Hashtable
sortedset
java.util.SortedSet
java.util.TreeSet
iterator
java.util.Iterator
n/a
Collection集合中的对象为Java类型。对于Hashtable和Map类型的对象,Castor同时存储其键和值。对于其映射,可以使用org.exolab.castor.mapping.MapItem类通过顶层(相对于嵌套类映射)类映射定义和嵌套类映射定义来描述。
u 检查<field> 节点中的“签名”属性(”direct”,”set-method” 和”get-method”
如果 ”direct” 属性设定为true,则在Java类定义中,该字段必须具有如下的声明:
public <type> <name>;
如果 ”direct” 属性 设定为 false 或者该属性被忽略, Castor 会通过该属性的存取方法访问该属性。首先,若设定了 'get-method' 'set-method' Castor 会访问如下方法签名:
public <type> <get-method>();
 
public void <set-method>(<type> value);
若没有设定'get-method' 'set-method'属性,Castor会尝试访问如下签名方法:
public <type> get<capitalized-name>();
public void set<capitalized-name>(<type> value);
<capitalized-name>是指Castor检查<name>属性值,将其首字母转换为大写,其他字符保持不变。
2.4.1 <field>节点的属性
<field>节点可以包含将Java字段映射为XML元素,数据库表列名称等信息。<field>节点可配置的属性如下:
Ø name: 该属性是必须的,即使在该映射类中没有该字段属性。如果配置了”direct”属性,”name”属性值必须是映射对象中的一个public字段(该字段必须是public,非static和非transient的类型)。如果没有”direct”和”get-/set-method”属性设定,“name”属性值对应的字段通过该值确定其访问方法(采用Java Bean规范)。
Ø type: 该字段属性的Java类型。Castor使用该信息将XML信息转换为Java对象信息(如将字符串转换为整型),定义该字段访问方法的签名。如果设定了”collection”属性,该属性信息用于指定集合中对象的类型信息。
Ø required: 在编组和解编过程中,该字段是否可选,默认值为false。
Ø transient: 如果设定为”true”,该字段在处理过程中将被忽略。
Ø direct: 如果为true,该字段在Java类定义中必须是public类型。
Ø collection: 如果该字段存在多个,则Castor使用该属性的设定来处理他们。该类型用于定义对应Java类中集合的类型。
Ø get-method: 可选配置,”name”属性对应Java类字段的访问方法,具体使用参考前文描述。
Ø set-method: 可选配置,”name”属性对应Java类字段的访问方法,具体使用参考前文描述。
Ø create-method: 工厂方法,用于构建FieldHandler实例。
2.4.2 <field>节点的子节点
在O/R Mapping中,<field>节点的子节点包含一个<sql>节点,用于描述如何将该字段属性映射的数据库表列信息。
2.5<sql>节点定义
<sql> 节点的用于描述Java 字段映射的数据库表列的详细信息。<sql> 节点的Schema 定义如下:
< xsd:element name =" sql ">
< xsd:complexType >
< xsd:attribute name =" name " type =" xsd:NMTOKENS " use =" optional "/>
< xsd:attribute name =" type " type =" xsd:string " use =" optional "/>
< xsd:attribute name =" many-table " type =" xsd:NMTOKEN " use =" optional "/>
< xsd:attribute name =" many-key " type =" xsd:NMTOKENS " use =" optional "/>
< xsd:attribute name =" read-only " type =" xsd:boolean " use =" optional " default =" false "/>
< xsd:attribute name =" transient " type =" xsd:boolean " use =" optional "/>
< xsd:attribute name =" dirty " use =" optional " default =" check ">
< xsd:simpleType >
< xsd:restriction base =" xsd:string ">
< xsd:enumeration value =" check "/>
< xsd:enumeration value =" ignore "/>
</ xsd:restriction >
</ xsd:simpleType >
</ xsd:attribute >
</ xsd:complexType >
</ xsd:element >
2.5.1 <sql>节点的属性
Ø name: 数据库表列名称。
Ø type: 对应数据库列的JDBC类型。Castor支持的JDBC类型及其别名列表如下,在数据处理过程中,Castor会自动在SQL类型和Java类型间进行转换:
SQL Type
Java Type
bigint
java.lang.Long
binary
byte[]
bit
java.lang.Boolean
blob
java.io.InputStream
char
java.lang.String
clob
java.sql.Clob
decimal
java.math.BigDecimal
double
java.lang.Double
float
java.lang.Double
integer
java.lang.Integer
longvarbinary
byte[]
longvarchar
java.lang.String
numeric
java.math.BigDecimal
real
java.lang.Float
smallint
java.lang.Short
time
java.sql.Time
timestamp
java.sql.Timestamp
tinyint
java.lang.Byte
varbinary
byte[]
varchar
java.lang.String
Ø read-only: 如果值为true,则数据库关系表中的该列将以只读方式操作。不会对其进行更新或删除操作。
Ø transient: 如果该属性值为true,JDO在数据库序列化操作时忽略该字段。如果用户希望在Castor XML编组解编过程中同时忽略该节点,可以通过设定<field>节点的“transient”属性。
Ø dirty:如果该属性值为“ignore”,则JDO在处理该字段的过程中将不检查数据库是否对该字段做了变更。
Ø many-key: 【用于一对多和多对多关系】指定该节点对应的<field>节点所表示的对象所映射的数据库表中外键的列名称。
Ø many-table: 【用于多对多关系】指定多对多关系中的关联中间表的名称。该关联中间表将关联双方联系起来。
说明:关于many-key及many-table属性参考下一节关联关系。
3. 关联关系
3.1关联关系概述
在Castor 中,对象之间的关联和依赖被区分为两种不同的关系。对于具有两种不同关系的多个对象,Castor 对这些对象的生命周期的维护是不同的。当两个对象为关联关系时,这两个对象必须各自进行创建(create ),删除(remove )和更新(update )。
在依赖关系中,一个对象必须在映射定义文件中显式的定义其Java 类“depends ”另一个Java 类。在映射定义文件中未声明依赖(depends )其他类的Java 类称为主对象类,在数据库中往往称之为主表。依赖于主类的其他对象类称之为依赖对象类或从表。在Castor 映射定义文件中,一个依赖对象类只能依赖于一个主类。
如果一个对象类依赖于其他类,在该类对象在Castor 中不能独立的创建,删除和更新。Castor 在事务操作过程中,不允许一个依赖对象实例变更其主对象实例。依赖对象和主对象必须都要有主键,要么不使用key-generator ,要么都使用key-generator 。
下述例子表明,对象类com.xyz.MyDependentObject 是一个依赖对象类,com.xyz.MyObject 是一个主对象类。MyDependentObject 依赖于MyObject 。
<mapping>
 <class name="com.xyz.MyDependentObject"
 depends="com.xyz.MyObject">
 ...
 </class>
</mapping>
3.2关联关系的处理
Castor 支持一对一,一对多和多对多的关联关系。多对多的关联关系中,由于每一个依赖对象只能有一个主对象,所以对象之间必须是关联(related )的而不是依赖(depends )的。
多对多关联关系中,必须有一个独立的表C 用于存储两个关联表A 和B 之间的关联信息。映射定义文件中<sql> 节点提供“many-key ”和“many-table ”两个属性表示这种关系。在多对多关系中,many-table 属性必须设定表C ;如果表A 中的主键名称不同于表C 中的外键的名称,则使用many-key 属性指定表C 中的外键的名称;如果表B 中的主键的名称不同于表C 中的外键的名称,则使用name 属性指定表C 中外键的名称。
下面以三个数据库表为例说明多对多关系的映射设定:
employee_table
id
name
salary
1482
Smith, Bob
$123,456
628
Lee, John
$43,210
1926
Arnold, Pascal
$24,680
department_table
id
name
comment
3
Accounting
7
Engineering
The very important department. :-)
employee_department
e_id
d_id
上述表中,employee 数据对象的映射关系举例如下:
<mapping>
 <class name="com.xyz.Employee" identity="id">
 <map-to table="employee_table"/>
 <field name="id" type="integer">
 <sql name="id"/>
 </field>
 <field>
 <sql many-table="employee_department"
 many-key="e_id" name="d_id"/>
 </field>
 <field name="salary">
 <sql name="salary" type="integer">
 </field>
 </class>
</mapping>
4. 延迟加载
Castor 支持在一对一,一对多及多对多的关联关系中使用延迟加载。使用延迟加载时,需要设定映射定义文件中<field> 的“lazy ”属性值为true 。
<mapping>
 <class name="com.xzy.Department">
 ...
 <field "employee" type="com.xyz.Employee" lazy="true" />
 ...
 </class>
</mapping>
如上所示,在一对一的关联关系中,当Castor 加载Department 对象时,将不会同时加载其引用的Employee 对象。只有使用Dempartment.getEmployee() 访问Employee 对象实例时,Castor 才会将Employee 对象数据从数据库加载到内存对象中。如果Employee 对象从未被访问过,则Castor 将永远不会加载该对象。
在一对多和多对多的关系中,如下所示:
<mapping>
 <class name="com.xzy.Department">
 ...
 <field name="employee" type="com.xyz.Employee" lazy="true"
 collection="collection"/>
 </class>
</mapping>
在集合中的Employee 对象只有在应用访问该集合中的对象时(如使用集合的iterator() 方法),Castor 才会加载该集合内的数据
5. 联合主键
Castor支持联合主键的设定。如果数据库表使用多列唯一标识一条记录,则可以在数据映射定义文件中设定多个主键。如果下面的映射定义文件所示:
<mapping>
 <class name="com.xyz.MyObject" identity="firstName lastName">
 <field name="firstName" type="string">
 <sql name="fname"/>
 </field>
 <field name="lastName" type="string">
 <sql name="lname"/>
 </field>
 ...
 </class>
</mapping>
多个主键在 <class> 节点的“ identity ”属性中以空格分隔。联合主键可以在主对象类,依赖对象类,各种关联关系(一对一,一对多和多对多)及延迟加载中使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值