TriActive JDO (TJDO) 是 Sun Java Data Objects (JDO) 1.0 规范的一个轻型的、开放源代码的实现。通过它,开发人员可以将一种透明的持久性机制用于任何JDBC 兼容的数据库和任何 Java 对象。在本文中,Java 开发人员 Jeff Gunther 通过一个例子介绍了 TJDO,这个例子示范了如何在MySQL 数据库中持久存储域模型。除了说明 TJDO 的特定实现细节之外,本文还回顾了 JDO 规范的基本概念和组件。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --> <!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
随着 Java 平台快速延伸到现代企业的每个角落,开发人员被淹没在新技术和新规范的缩写词中,每一个都许诺解除各种 IT 病痛。即使在 Java 社区内部,对于开发人员和管理者来说,也同样难以断定哪种技术只是昙花一现,哪种技术能够生存下去。如果抽查一些 Java 开发人员,询问他们在应用程序中如何持久存储数据,您可能会得到各种不同的答案。有些答复可能是对关系数据库使用基本的 JDBC,有些可能使用纯面向对象的数据库,而另一些可能在应用程序服务器中使用 Container Managed Persistence 2.0 (CMP) 。尽管这些方案能够而且确实为开发人员提供了持久性服务,每种技术都有各自不同的缺点、局限和代价。
与 Java 社区中的其他项目类似,JDO 规范是通过 Java Community Process 按照 Java Specification Request 12 创建的。JDO 架构师的主要目标之一是,向开发人员提供一种透明的机制,不考虑底层数据存储方式处理和操作持久信息。从一开始,它就被设计成让开发人员逃避开发持久性基础设施的苦差事。因为开发人员使用的通用 API 可以跨越不同的数据存储进行互操作,开发团队就可以延迟决定特定项目将使用或支持什么样的数据存储方式。这些好处都减少了编码的工作量,使开发人员能够关注项目的其他相关领域。与 Java 家族中的其他规范相似,JDO 消除了锁定到特定供应商的危险。每个供应商的 JDO 实现都提供了一套不同的支持数据源的特性和类型。根据项目的要求和预算,与其他的相比某个供应商可能更有吸引力。
|
源代码
如果您和多数开发人员一样,学习一项新技术就是一个不断尝试和出错的反复过程。为了帮助您迅速进入 TJDO 的探索之旅,拓展对 JDO 的一般了解,本文提供了一个完整的构造包、一系列配置文件和示例源代码(资源包和其他相关技术的链接,请参阅 参考资料)此外,如果需要把 TJDO 集成到其他项目中,提供的这些包和 Ant 构造脚本可以帮助您完成集成工作。 |
|
在不购买许可证的前提下,为了让您有机会尝试 JDO,我们使用了 TriActive JDO (TJDO),JDO 1.0 规范的一个轻型的、开放源代码的实现。TJDO 支持多种 JDBC 兼容的数据库作为数据存储方式。
环境要求
为了使用提供的文件对 TJDO 进行完全测试,您的环境需要满足以下最低要求:
- 安装有 Java 2 SDK, Standard Edition 1.4 或以上版本
- 安装有 Apache Ant 1.5.3 或以上版本
- 安装有 MySQL Server 4.0.14 或以上版本
这些技术的链接请参阅 参考资料。 注意,尽管 Ant 构造脚本应该是跨平台的,这些示例类只在 Microsoft Windows XP 上测试和验证过。在开始讨论一些代码和 JDO 基础之前,我们首先要安装并配置源代码。
安装和配置示例代码
为了安装源代码包,需要完成以下步骤:
- 下载 源代码 包。
- 将 j-tjdo.zip 文件解压到一个临时目录。
- 在 MySQL 环境中创建名为 tjdo 的数据库
- 打开
common.properties
文件,修改 MySQL 键/值对,以匹配您的环境。下面是一个例子:
... mysql.server=127.0.0.1 mysql.database=tjdo mysql.user=root mysql.password=
|
使用 TJDO 的步骤
本文的基本目标是,为您在应用程序中开始使用 TJDO 提供必要的知识和信息。在讨论如何测试提供的示例代码之前,我首先回顾一些使用 TJDO 所需要的一般步骤。您会发现许多步骤也适用于其他的 JDO 实现。继续阅读本文之前并不需要完全了解这些步骤,这只是为您将来的项目勾勒一个大纲。本文提供的源代码包,在其开发过程中经历了其中的每个步骤。
- 用普通的原 Java 对象(POJO)创建域模型。
- 创建支持应用程序代码。
- 编译类。
- 创建 XML 元数据文件,描述域类的持久性行为。
- 增强编译后的类的字节码。
- 如果使用关系数据库作为数据存储,创建适当的数据库架构。
示例域模型
为了便于回顾 JDO 的基本概念和 API,示例源代码中包含一个简单的域模型。图 1 表示 POJO 的 UML 图。在这个例子中, Developer
实例代表开发软件的某个雇员。类似地, Manager
实例代表管理其他雇员的特殊雇员, Location
实例代表雇员、开发人员和管理人员工作的物理建筑物。
图 1. Java 对象的 UML 图
这些域类和支持类一起把数据持久存储到 MySQL。
JDO API 基础
现在我们已经介绍了如何配置工作环境和基本的域模型,接下来将讨论如何使用 JDO API 把这些对象及其关系持久存储到 MySQL。因为本文只对 JDO 和 TJDO 进行一般性介绍,不会详细讨论 JDO API 的具体特性。如果希望进一步了解某些组件,您可以在 参考资料 中找到 JDO 1.0 规范的链接。
清单 1 中的代码片段说明了连接 JDO 和 MySQL 所需的初始属性。
清单 1. TJDOTest.java 文件
0 ... 1 public static void main(String[] args) 2 { 3 Properties props = new Properties(); 4 5 props.setProperty("javax.jdo.PersistenceManagerFactoryClass", "com.triactive.jdo.PersistenceManagerFactoryImpl"); 6 7 props.setProperty("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver"); 8 props.setProperty("javax.jdo.option.ConnectionURL", "jdbc:mysql://" + args[0] + "/tjdo?autoReconnect=yes"); 9 props.setProperty("javax.jdo.option.ConnectionUserName", args[1]); 10 props.setProperty("javax.jdo.option.ConnectionPassword", args[2]); 11 props.setProperty("com.triactive.jdo.autoCreateTables", "true"); 12 13 PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props); 14 PersistenceManager pm = pmf.getPersistenceManager(); 15 16 Transaction tx = pm.currentTransaction(); 17 18 try 19 { 20 tx.begin(); 21 ...
|
让我们看一看代码中的主要部分:
- JDO 规范要求每个 JDO 供应商都提供一个类实现
PersistenceManagerFactory
。 PersistenceManagerFactory
用于获得 PersistenceManager
实例。 PersistenceManager
是开发应用程序支持代码使用的主要接口,负责把数据持久存储到 MySQL。
- 第 7 到 10 行定义了和 MySQL 的连接细节。传递给该类的每个参数都定义在
common.properties
文件中,该文件位于生成目录的根目录下。
- 如果参数不存在,第 11 行要求 TJDO 在运行时自动在 MySQL 中创建支持表。
- 第 13 到 14 行,属性被传递给一个帮助器类,创建了一个
PersistanceManagerFactory
和一个 PersistanceManager
。
- 第 16 到 20 行从
PersistanceManager
创建一个 Transaction
对象并启动它,保证所有数据在事务级上是一致的。
清单 2 说明了操作和用数据填充的域模型。首先要创建一个 Location
对象,然后创建两个雇员: Developer
和 Manager
。最后,我们向 Location
增加新建的雇员。
清单 2. TJDOTest.java 文件
... Location location = new Location(); location.setName("SomeLocation"); location.setAddressLine1("1234 Some Street"); location.setAddressLine2("Suite 111"); location.setZipcode("12345"); ArrayList employees = new ArrayList(); ArrayList developers = new ArrayList(); Developer developer = new Developer(); developer.setFirstName("Jane"); developer.setLastName("Doe"); developer.setLocation(location); employees.add(developer); developers.add(developer); Manager manager = new Manager(); manager.setFirstName("John"); manager.setLastName("Smith"); manager.setLocation(location); manager.setEmployees(developers); employees.add(manager); location.setEmployees(employees); ...
|
清单 3 中的代码片段展示了 JDO 的优美之处。清单 2 中创建的每个对象传递给 PersistanceManager
的 makePersistent
函数。仅此而已。魔术般地,所有数据都被添加到数据库中。您完全不需要担心任何 SQL INSERT
语句、数据库连接或者关系表。TJDO 全部完成了取得对象和向数据库插入数据的工作。
清单 3. TJDOTest.java 文件
... pm.makePersistent(developer); pm.makePersistent(manager); pm.makePersistent(location); tx.commit(); ...
|
创建 XML 元数据文件
为了把支持应用程序代码和域模型结合起来,首先要创建一个 XML 元数据文件,描述具有持久性能力的类。在字节码增强过程中和运行期间将使用这些文件。必须为每个类创建名为 <类名>.jdo
的文件。清单 4 给出了这个域模型中所用的 Location.jdo
文件:
清单 4. Location.jdo 文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE jdo PUBLIC "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN" "http://java.sun.com/dtd/jdo_1_0.dtd"> 3 4 <jdo> 5 <package name="test"> 6 <class name="Location" identity-type="datastore"> 7 <field name="employees"> 8 <collection element-type="Employee"> 9 </collection> 10 </field> 11 <field name="name"> 12 <extension vendor-name="triactive" key="length" value="max 50"/> 13 </field> 14 <field name="addressLine1"> 15 <extension vendor-name="triactive" key="length" value="max 100"/> 16 </field> 17 <field name="addressLine2"> 18 <extension vendor-name="triactive" key="length" value="max 100"/> 19 </field> 20 <field name="zipcode"> 21 <extension vendor-name="triactive" key="length" value="max 5"/> 22 </field> 23 </class> 24 </package> 25 </jdo>
|
让我们分析一下这个 XML 文件中的重要成分:
- 第 6 到 23 行定义了类属性和适当的字段元素。类元素的第二个属性称为
identity-type
。TJDO 只支持 datastore
作为它的 identity 类型。
- 第 7 到 10 行定义了一个集合字段。这个字段用于存储在特定办公地点工作的雇员。集合元素的
element-type
属性定义存储在集合中的类的类型。
- 第 11 到 22 行定义各种字符串字段,TJDO 使用 extension 元素确定 MySQL 表的属性。
关于 JDO 元数据文件各种元素和属性的更多信息,请参阅 参考资料。
生成、改进和测试示例代码
要编译、生成和测试程序包,按以下步骤:
- 检查 MySQL 数据库服务器中是否已经建立了称为
tjdo
的数据库。
- 在解压源代码的目录中键入
ant clean
以清理环境。
- 键入
ant
启动生成过程。
如果环境满足要求并且配置正确,您将看到与清单 5 类似的结果:
清单 5. 生成过程成功地输出结果
Buildfile: build.xml init: [mkdir] Created dir: D:/TJDO/tjdo/dist compile-common: compile-module: [echo] Compiling ... [mkdir] Created dir: D:/TJDO/tjdo/build [mkdir] Created dir: D:/TJDO/tjdo/build/classes [javac] Compiling 5 source files to D:/TJDO/tjdo/build/classes enhance: [copy] Copying 4 files to D:/TJDO/tjdo/build/classes [apply] Enhancing class test.Employee [apply] Enhancing class test.Developer [apply] Enhancing class test.Location [apply] Enhancing class test.Manager [apply] done. package-common: [jar] Building jar: D:/TJDO/tjdo/dist/tjdo-demo.jar default: BUILD SUCCESSFUL Total time: 5 seconds
|
键入 ant test
测试给出的代码。如果环境设置正确,MySQL 中的 tjdo
数据库将包含所有的 Location
、 Developer
和 Manager
数据。
结束语
TJDO 是 Sun Java Data Objects (JDO) 1.0 规范的一个开放源代码的实现,为开发人员提供了一种很棒的方式,无论底层数据存储如何都可以透明地持久存储数据。尽管 JDO 规范的发展还刚刚起步,它已经填补了 Java 社区中的一个空白。JDO 实现(比如 TJDO)把关系数据库和面向对象的 Java 语言相结合,为开发人员提供了一个现在就可以使用的功能强大的工具。为了帮助您完成这项任务,示例程序包提供了一个生成和打包的框架,可用于把 TJDO 合并到您的项目中。
参考资料
关于作者
|
|
|
Jeff Gunther 是 Studio B 的作者,也是 Intalgent Technologies 的总经理和创始人,这家公司是新兴的软件产品和解决方案提供商,其产品采用 Java 2 Enterprise Edition 和 Lotus Notes/Domino 平台。Jeff 是一位应用程序和基础设施架构师,具有架构、设计、开发、部署和维护复杂软件系统的经验。他丰富的经验包括运行于多平台上的软件的整个生命期的开发,从 Web 服务器直到嵌入式设备。Jeff 从早期的“Mosaic 以前”时代开始就投身于因特网行业。可以通过 [email protected] 和 Jeff 联系。 |