UML软件工程组织

用JDO替代CMP的应用
作者:易飞    本文选自:开放系统世界——赛迪网  2002年12月24日

在大多数使用EJB的项目中,O/R Mapping一直是Java开发者关注的问题。自从有了CMP(Container Managed Persistence),数据库映射需要做的工作轻松多了。然而,CMP仍然有不完善的地方——针对不同的应用服务器,CMP的映射描述文件不同,这在一定程度上阻碍了EJB的移植;CMP/CMR与数据表的映射关系比较复杂。经笔者测试,使用Castor JDO(Java数据对象)比使用CMP性能有很大的提高,而且能满足大多数应用的需求。

关于Castor JDO

Castor JDO是一个以RDBMS为中心的开放源码项目,虽然它与Sun的JDO有很多相似之处,但没有完全遵循JSR规范。一些主要技术上的差异使它与Sun的JDO规范并不十分相符。每一个持久对象在Castor中都有一个被观察的数据锁,这意味着事物的超时和死锁可以不被视为数据锁定。而Sun的JDO规范却隐藏了锁的细节。

内部的Castor JDO对每个事物活动的持久对象都提供一个数据锁的拷贝(包括缓存)维护。Sun的JDO未明确要求每一个事物的每一个对象用缓存,但它含蓄地要求具有字节码修饰者,而Castor却不需要。

Castor还提供一些Sun的JSR规范中没有提到的其它特性,比如键值生成器(常用于ID自动生成)、长时事务支持和OQL等。

Castor JDO和EJB CMP

JDO和EJB Bean之间的关系很难用谁比谁更好来形容。实体Bean可以管理自身的持久性(EJB规范称为Bean管理的持久性或BMP),也可以依赖EJB容器来管理它(称为容器管理的持久性或CMP)。

对于BMP,实体Bean可以用Castor JDO作为持久性机制,或者使用其它的办法,比如直接使用JDBC作为持久性机制。对于CMP,EJB容器供应商可以在Castor JDO之上实施CMP,这样Castor JDO就被用来作为实体Bean的持久机制。

如果开发者需要EJB的管理生存周期、安全性、“一次开发随意部署”的承诺和分布式商业应用等特性,那么EJB是正确的选择。然而事实上,Castor的简洁、开放性、更多设计上的自由度和与Castor XML整合等特性,让人有充分的理由选择Castor JDO。庆幸的是,我们可结合EJB和Castor JDO的长处来弥补它们各自的短处,这就是本文的目的。

Castor JDO结合SessionBean使用

选择应用服务器

目前只有JBoss有支持Castor JDO的包。Castor会在将来的版中提供对J2EE的支持。笔者使用JBoss-2.4.9作为测试。如果选择Castor JDO完全替代CMP,可以不考虑使用支持最新CMP版本的应用服务器。

选择Castor JDO

为了获得最新版本的支持,可以选择最新的Castor JDO包。笔者测试时使用的版本是0.9.4。

配置JBoss

1.修改conf/default/jboss.jcml文件

<!-增加JDBC驱动-->
<mbean code="org.jboss.jdbc.JdbcProvider" name="DefaultDomain:service=JdbcProvider">
     <attribute name="Drivers">oracle.jdbc. 
driver.OracleDriver,org.hsqldb.jdbcDriver</attribute>
</mbean>
...
<!--配置JDBC数据源-->
<mbean code="org.jboss.jdbc.XADataSourceLoader" 
name="DefaultDomain:service=XADataSource,name=NewsDS">
    <attribute name="PoolName">NewsDS</attribute>
 <attribute name="DataSourceClass">org.jboss.pool.j 
dbc.xa.wrapper.XADataSourceImpl</attribute>
    <attribute name="Properties"></attribute>
    <attribute name="URL">jdbc:oracle:thin:@192.168.1.7:1521:NEWS</attribute>
    <attribute name="GCMinIdleTime">1200000</attribute>
    <attribute name="JDBCUser">scott</attribute>
    <attribute name="MaxSize">10</attribute>
<attribute name="Password">tiger</attribute>
...
</mbean>
...
<!-在文件最后配置CastorJDO-->
<mbean code="org.jboss.jdo.castor.CastorJDOImpl"  
name="DefaultDomain:service=CastorJDO,name=castortestnews">
    <attribute name="Configuration">file:../jdo/conf/database.xml</attribute>
    <attribute name="JndiName">jdo/castortestnews</attribute>
    <attribute name="LockTimeout">10000</attribute>
    <attribute name="LoggingEnabled">true</attribute>
    <attribute name="CommonClassPath">false</attribute>
<attribute name="AutoStore">false</attribute>
<!-Castor JDO新版本中提供连接池-->
<attribute name="DatabasePooling">true</attribute>
</mbean>

2.修改conf/default/standardjaws.xml文件

<datasource>java:/NewsDS</datasource>
<type-mapping>Oracle8</type-mapping>
<debug>true</debug>

3.拷贝必要的jar包到lib/ext目录下

这些包包括:Castor JDO包castor-0.9.4.jar、JBoss2.4.x的Castor JDO补丁包castorjdoplugin.jar、JDBC驱动(笔者使用的是Oracle 8.1.7)classes12.zip、XML解析包xerces-J_1.4.0.jar(笔者使用的是Castor推荐的xerces版本)。

配置Castor JDO

增加%JBOSS_HOME%\jdo\conf\database.xml文件,文件代码如下:

<!DOCTYPE databases PUBLIC "-//EXOLAB/Castor JDO Configuration DTD Version 1.0//EN" 
 "http://castor.exolab.org/jdo-conf.dtd">
<database name="news" engine="oracle">
    <!-下面的jndi name与standardjaws.xml中的datasource对应-->
    <jndi name="java:/NewsDS" />
   <!--路径可以由读者指定,但父目录必须是%JBOSS_HOME%-->
    <mapping href="../jdo/conf/mapping.xml" />
</database>

安装Ant

使用Ant编译部署EJB应用,可以下载安装Ant的最新版本(笔者使用的是Ant-1.5.1)。

在SessionBean中封装JDO的方法,可以参考Castor的文档。注意,作为参数传递的JDO Bean,需要实现Java串行化接口。封装JDO的代码如下:

//ejbCreate方法中查询JDO
	ctx = new InitialContext();
	jdo = (DataObjects) ctx.lookup("java:comp/env/jdo/CastortestnewsJDO");
  //创建新对象,增加数据表中的一行
 /**每一个查询或更新的方法打开新的db连接,使用后关闭,不关闭的连接会导致TransactionNotInProg
ress异常*/
	db = jdo.getDatabase();
	auxType.setAuxDesc(auxDesc);
	db.create(auxType);
	db.close();


在其它应用服务器上使用Castor JDO

针对不同的应用服务器,需要增加一个Castor JDO JNDI绑定的服务,为Castor JDO配置参数。例如,JBoss增加了一个JMX MBean的服务,提供了JBoss 实现Castor JDO MBean绑定服务的源码。



版权所有:UML软件工程组织