随着 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 实现都提供了一套不同的支持数据源的特性和类型。根据项目的要求和预算,与其他的相比某个供应商可能更有吸引力。
在不购买许可证的前提下,为了让您有机会尝试 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 所需要的一般步骤。您会发现许多步骤也适用于其他的 JDO 实现。继续阅读本文之前并不需要完全了解这些步骤,这只是为您将来的项目勾勒一个大纲。本文提供的源代码包,在其开发过程中经历了其中的每个步骤。
- 用普通的原 Java 对象(POJO)创建域模型。
- 创建支持应用程序代码。
- 编译类。
- 创建 XML 元数据文件,描述域类的持久性行为。
- 增强编译后的类的字节码。
- 如果使用关系数据库作为数据存储,创建适当的数据库架构。
为了便于回顾 JDO 的基本概念和 API,示例源代码中包含一个简单的域模型。图 1 表示 POJO 的 UML 图。在这个例子中,
Developer
实例代表开发软件的某个雇员。类似地,
Manager 实例代表管理其他雇员的特殊雇员,
Location
实例代表雇员、开发人员和管理人员工作的物理建筑物。
图 1. Java 对象的 UML 图
这些域类和支持类一起把数据持久存储到 MySQL。
现在我们已经介绍了如何配置工作环境和基本的域模型,接下来将讨论如何使用 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 元数据文件,描述具有持久性能力的类。在字节码增强过程中和运行期间将使用这些文件。必须为每个类创建名为
<类名>.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 合并到您的项目中。
- 您可以参阅本文在 developerWorks 全球站点上的
英文原文.
- 下载本文中所用的示例
源代码。
- SourceForge 上的
TJDO 项目页,提供了您开始使用这一
JDO 实现所需要的全部信息。
- 请参阅
Java Data Objects
specification。
- 访问
IBM
developer kits页面,查看 IBM 所提供的 Java 技术 SDK 列表。
- 从 Apache Software Foundation 下载
Ant
1.5.4。
- 从 MySQL AB 下载
MySQL
4.0.14。
- 作为 JDO 的优秀入门读物,Paul Monday 的教程“
JAVA数据对象上机实践” (
developerWorks,2002 年 7 月)是一个很好的起点。
-
JDO Central 是内容丰富的 JDO 开发者资源网站,无论是经验丰富的开发老手还是初学者都很适合。尤其是,基于
Web 的论坛更是交流和分享 JDO 观点的一种极好方式。
- 在
developerWorks
Java 技术专区
可以找到数百篇有关 Java 编程各个方面的文章。
Jeff Gunther 是 Studio B 的作者,也是 Intalgent Technologies 的总经理和创始人,这家公司是新兴的软件产品和解决方案提供商,其产品采用 Java 2 Enterprise Edition 和 Lotus Notes/Domino 平台。Jeff 是一位应用程序和基础设施架构师,具有架构、设计、开发、部署和维护复杂软件系统的经验。他丰富的经验包括运行于多平台上的软件的整个生命期的开发,从 Web 服务器直到嵌入式设备。Jeff 从早期的“Mosaic 以前”时代开始就投身于因特网行业。可以通过 jeff.gunther@intalgent.com 和 Jeff 联系。