使用 Rational Application Developer,DB2 及 WebSphere Application Server 来自底向上创建 JPA 实体

使用 IBM DB2 Identity Value Generation 功能以及其他高级的设计选项

学习怎样从已存在的关系表中创建 Java Persistence Architecture(JPA)实体,使用由数据库生成的主键值,并作为一个或者多个 JPA 实体 bean 组合(或者集合)的一部分。

Ali Manji, 软件分析师, IBM

Ali Manji 的照片Ali Manji 是 IBM 多伦多实验室的一名软件工程师。他在 Rational Service and Accelerated Value 团队工作。


developerWorks 投稿作者

2010 年 11 月 22 日

下载 Rational Application Developer 试用版  |   在线试用 Rational Application Developer
获取免费的 Rational 软件工具包系列,下载更多的 Rational 软件试用版

本文的关注点是 Java™ Persistence Architecture(JPA)实体及其特征的创建:

  • 从已存在的关系表格(有时引用为“自底向上”的方法)中生成它们。
  • 它们为 ID 属性使用数据库生成的主键值。
  • 它们是一个或者多个其他 JPA 实体 bean 组成的一部分(例如,一对一或者多对一的关系)。

为了对 JPA 实体权衡数据库生成的主键值,您要使用到 IBM® DB2® 内构及方便的 Identity Value Generation 功能。

尽管本文并不关注这些方面,但是程序将会使用一个 Enterprise JavaBean™(EJB)3.0 Stateless Session Bean 以及一个使用 Servlet 2.5 规格的 servlet。

开始之前的注意事项

您要使用到 Java™ Enterprise Edition(JEE)5.0 规格,来开发程序。为了构筑程序,您要使用到:

  • IBM® Rational® Application Developer 7.5.5
  • IBM® DB2® Server Edition 9.5.5 for Windows
  • IBM® WebSphere® Application Server 7.0.0.7(通过使用可通过 Rational Application Developer 获得的 WebSphere Test Environment)

注意
为了重复本文中的步骤,您需要像安装 Rational Application Developer 7.5.5 版本一样在 Microsoft® Windows® 机器上安装 DB2 Server Edition 9.5.5 版本。

在构建时您需要使用到一些资源,包括为企业 Java 程序创建初始 DB2 数据库与一些工件的脚本。

resources568.zip 文件解压缩到您所选择的文件系统之上。它应该包括有两个文件: createMembersDB.sql AcmeMembershipApplication.ear


处理 ACME 成员系统

图 1 显示了 Acme 成员子系统的物理关系数据库。

图 1. Acme 成员数据模型
Membership 数据库五个表的图

为了接受 Acme Co. 的服务和优势,客户必须成为成员之一。客户可以从 Single,Student 或者 Family 成员(Membership 表中的 membership_type 自动说明了成员的类型)选择一个。Family 成员提供了 Acme 的服务给那些夫妇以及未满 18 周岁的未成年人。为了将成员维持在“良好的状态”,客户每年必须更新一下他们的成员权。

所有的成员权最多拥有一个 主要成员。主要成员对维护成员权的良好状态负主要责任,并支付每年的会员费。

除了拥有一个主要成员,一个家族成员权正常情况下拥有一个或者多个附属人员。在家族成员中有两种类型的附属成员:配偶以及未满 18 周岁的未成年人。

Acme 公司及其成员之间的所有联系都通过主要成员来进行。处于这个目的考虑,Acme 会从主要成员那里收集所有成员的地址以及联系方式等信息。

导入 Acme 成员数据库

Acme 的成员数据库就是其成员子模块的核心组成部分。开始时您应该先将 Acme 的成员数据库方案导入到 DB2 之中。

  1. 从您的 Windows 开始菜单中,选择 Start >All Programs > IBM DB2 > DB2Copy1(Default)> Command Line Tools > Command Editor
  2. 从 Command Editor 菜单栏中,点击 Selected > Open,并切换至解压缩 createMembersDB.sql 文件的位置。
  3. 从 DB2 Command Editor 窗口的菜单栏中选择 Selected > Execute,来执行 SQL DDL 声明。
  4. 选择 Command Editor > Exit 来成功地执行 SQL 与 DDL 命令。

使用 DB2 Identity Value Generation 功能

数据库为一个表格的主键生成值(通过扩展,为相关表生成外主键),从而将程序从这项任务的重担中解放出来。这就是说,程序不需要为程序之中的永久性对象生成单独的键值,而允许将注意力放到核心业务逻辑以及业务规则之上。这对提高程序的可维护性和可读性上面有积极的意义。

Acme 的主要数据和程序结构想要使用 DB2 Identity Value Generation 功能来从不同程序的业务逻辑这样的重担移去。为了权衡使用这项功能,JPA 可以延缓向关系数据库分配实体的 ID。

配置功能

在前面的章节之中,通过运行提供的 SQL 脚本您导入了数据库。但是,您仍然需要配置 MEMBERSHIP 表的主键,以使用 DB2 的 Identity 值生成功能。

  1. 从 Windows 之中,选择 Start >All Programs > IBM DB2 > DB2Copy1(Default)> General Administration Tools > Control Centre
  2. 在 Control Center 的左部树形视图窗格中,展开 All Databases >MEMBERS 文件夹,并选择 the Tables 文件夹。
  3. 从 Control Center 中上部表格的相应列表之中,选择 Membership 表格,右击,并选择 Alter 以启动 Alter Table 对话框窗口(参见图 2)。
图 2. 更改列属性的 Alter Table 对话框窗口
Alter Table – MEMBERHIP 视图
  1. 在 Alter Table 对话框窗口之中,选择 ID 列并点击 Change 按钮,这将会启动 Change Column 对话框窗口。
  2. Change Column 对话框窗口之中,点击 Value generation 项。
  3. 选择如图 3 所示的 Identity 单选按钮并点击 OK
  4. 再次点击 OK 以关闭 Alter Table 对话框,并完成对 MEMBERSHIP 表格所做的更改。
图 3. 更改主键以使用 Identity Value Generation 功能
Change Column 对话框窗口

设置主键值以使用 Identity Value Generation 功能,有一些很有意思需要注意的地方:

  • 选择 Identity 同样使得列成为空白变得不可能。这就是说,该字段同样会在每一行中存储一个生成的值。
  • Initial valueIncrement 字段(如图 3 所示)可以设置初始行与每一个随后行的值。

注意:
在图 3 中,您要使用 Change Column 对话框窗口来编辑已存在表格的主键值。您还可以选择,定义主键值,来在定义表格和添加主键值列本身时使用 Identity 值生成。

在您生成 JPA 实体,您需要执行下列步骤:

  1. 导入拥有一个 EJB 项目和一个 Web 项目的 JEE 5.0 Enterprise Application Project 的开始部分
  2. 创建对 DB2 Membership 数据库的活动链接

将成员程序导入到 Rational Application Developer

  1. 使用您所选择的工作区位置来启动 RAD 7.5.5。Start > IBM Software Delivery Platform > IBM Rational Application Developer 7.5
  2. 当您需要输入工作区的位置时,您可以选择提供的默认位置,或者输入另一个方便的位置。
  3. 如果欢迎界面出现的话,您可以继续操作并将其关闭掉。
  4. 导入您所构建的初始 EAR 项目。
    1. 从菜单栏中选择 File > Import > Java EE > EAR File ,然后点击 Next
    2. 点击 Browse 按钮并切换至您保存文件 AcmeMembershipApplication.ear 的位置,并选中它以进行导入。
    3. 点击 Finish。您不需要继续去看 Import 向导的其他页面了。

通过成功的导入,您就会看到一个如图 4 所示的项目布局页面。总共会有三个项目:一个 Enterprise Application 项目以及相应的 Web 模块项目以及 EJB 模块项目。

在 Problems 视图中您将会看到一系列的错误,在创建 JPA 实体之前您可以一直忽略它。

图 4. Acme 的实体程序项目
Enterprise Explorer 项视图显示了 3 个项目

EJB 项目拥有一个会话 EJB,您可以使用它来调用 JPA 实体来创建新的成员以及成员类型。

网络项目拥有一个简单的 servlet,您可以在 WebSphere Test Environment 下使用它以调用您的业务逻辑。

创建数据连接

为了让 Rational Application Developer 意识到本地 DB2 服务器上已存在的 MEMBERS 数据库,您需要创建一个该数据库与 Rational Application Developer 之间的数据联系。

  1. 从 Java EE Perspective 切换至 Data Perspective。选择 Window > Open Perspective > Other > Data
  2. Database Connections 文件夹之下的 Data Source Explorer 视图之中,您可以看到列出的 MEMBERS 数据库。右击并选择 Properties
  3. 在 Properties 窗口之中,选择 Driver Properties 项,并在该界面之中,输入 DB2 账号用户名和密码。处于方便的考虑,请确定选中了 保存密码 复选框。
  4. 点击 Test Connection 按钮来试着连接。在您看到一条 Ping succeeded! 的信息之后点击 OK
  5. 再一次点击 Database Connections 之下的 MEMBERS 数据库,右击并选择 Connect

生成 JPA 实体

在这一部分中,您将会从 MEMBERS 数据库中生成 JPA 实体,这一操作是从业务逻辑的核心部分来为 Acme 的成员系统所完成的。

首先,您要创建一个 JPA 项目以放置您的 JPA 实体 beans:

  1. 切换至 JPA 视角。选择 File > New > JPA Project 以打开 New JPA Project 向导、
  2. 对于 Project 名字,您可以输入 AcmeMembershipApplicationDomain,然后点击 Next
  3. Connection 下列菜单之中,选择 MEMBERS 数据库连接。
  4. 选中 Override default schema from connection 复选框,然后从 Schema 下拉菜单之中为您的数据库选择适当的 DB2 方案。
  5. 点击 Finish

既然您已经创建了一个 JPA 项目,那么您就可以生成自己的 JPA 实体了:

  1. 右击新的您所创建的 JPA 项目,AcmeMembershipApplicationDomain,并选择 JPA Tools > Add JPA Manager Beans > Generate Entities
  2. Generate Entities 向导的第一个页面将会让您选择适当的对 DB2 数据库的 链接 以及方案。基于您是如何创建 JPA 项目的,默认选择是列出适当的数据库与方案。如果不是,那么您可以为您的 DB2 实例选择适当的 DB2 连接,然后点击 Next 按钮。
  3. 对于 Package 字段,您可以输入 org.acme.membership.domain
  4. 选中 Synchronize Classes in persistence.xml 复选框。
  5. 点击 Select All 按钮以选中向导中该页面内所列出的表格。
  6. 点击 Finish

提示
尽管尚不明显,但是 Entity Name 列中所出的实体(如图 5 所示)是可编辑的。这就是说,您可以更改所提供 JPA 实体的默认类名。在图 5 中,通过将 Contactinfo 重命名为 ContactInfo ,而 Primarymember 重命名为 PrimaryMember,演示了这两个实体。

图 5. 生成 JPA 实体的关系数据库表
显示两个列: Table,Entity Name

请在 AcmeMembershipApplicationDomain 项目之中自由浏览生成的 JPA 实体。

注意:
Rational Application Developer 7.5.5 中提供的工具,可以生成 JPA 实体 bean,以将数据库表列字段映射到 JPA 实体相应属性的适当类型。

既然您已经有了 JPA 实体,那么您就可以矫正工作区内存在的错误了,这一切都是根据 JPA 实体的引用而计算的。

  1. 从 Project Explorer 视图中右击 AcmeMembershipApplicationEJB 项目,并选择 Properties
  2. 选中 AcmeMembershipApplicationDomain 项目旁边的框,如图 6 所示,然后点击 OK 按钮。
图 6. 为项目设置 Java EE 模块附件
Properties 窗口:Java EE Module Dependencies 视图

调整 JPA 实体

生成的 JPA 实体只是一个起始点。在进行进一步的业务逻辑修饰之前,它们需要调整和改进。需要进行调整以利用可得到的语言便利,并确保实体更精确反映了业务和程序域。

您要做出这些调整以生成您的 JPA 实体:

  1. 进一步地指定独一的主键值(标为 @Id 注释),取决于生成值的数据库。
  2. 为了权衡 java.util.GregorianCalendar Java 类型的使用,以获取和控制 java.sql.Timestamp Java 类型之上的数据,当您才创建 JPA 时,它就是选中的默认类型。
  3. 为了全面使用数据库,您可以将一些实体的关系理解为一对一而不是多对一。这不会影响到成员数据库中表格之间的主-外键关系。这样做的一个原因就是使用程序逻辑,以更好地反映业务逻辑结构,以及实体之间存在的限制性因素(它代表了真实对象的抽象程度以及对象之间的关系)。

指定 JPA 实体的自动 ID 生成

您要调整您的 JPA 实体,使用 Identity Generation 方案以将 ID 属性指定为数据库所生成的独特值。

  1. 打开 PrimaryMember 类。
  2. 切换至 JPA 视角,并在 JPA Structure 视图(通常在 JPA 视角的右上角)中,选择 id 属性(参见图 7)。您可以选择,您可以选择 Java 编辑器之中的 id 属性。
图 7. PrimaryMember 类的 JPA 实体
JPA Structure 项视图
  1. JPA Details 编辑器之中(通常位于 JPA 视角的右下部),选中 Primary Key Generation 复选框并从 Strategy 菜单中选择 Identity ,如图 8 所示。
图 8. 指定 Identity 主键生成策略的使用
JPA Details 项视图

如图 9 所示,注意您的 ID 属性现在拥有一个与其相关的附加性注释。

图 9. ID 属性的附加性注释,包括 Primary Key Generation 策略
GeneratedValue 注释
  1. 对于该项目之中的其他 JPA 实体重复 1–3 步( AddressContactInfoDependent 以及 Membership)。

更改属性的默认类型

Rational Application Developer 中的 JPA 规格与工具,从 DB2 映射到 JPA 类中的属性。对于一个语言和业务逻辑视图,可能存在一些情况,就是其他的 Java 类型使用起来更加的方便。

一个很好的例子就是 java.sql.Timestamp 类型,对于 DB2 TIMESTAMP 列类型 JPA 工具在默认条件下会使用到它。Java 开发员和结构师拥有使用该默认选择或者其他兼容类型的选择。

Acme 成员管理权系统的开发员与结构师,选择使用 java.util.GregorianCalendar 而不是默认的 java.sql.Timestamp。使用 java.util.GregorianCalendar 提供了一些方法和操作,开发员可以发现对程序来说这些方法和操作非常的方便。

  1. 打开 PrimaryMember 类。
  2. 在 Java 编辑器之中,重构出生日期编辑类型 java.util.GregorianCalendar 而不是 java.sql.Timestamp。对于这一步,您必须更新两项内容:
    1. 导入的类
    2. get 与 set 方法(getbirthdate, setbirthdate)以使用 java.util.gregoriancalendar
  3. 在 JPA 视角下,从 JPA Structure 视图中(通常在 JPA 视角的右上部),选择 birthdate 属性。
  4. JPA Details 编辑器中(通常位于 JPA 视角的右下部),从 Temporal 下拉菜单之中,选择 Timestamp,如图 10 所示。
图 10. 设置临时性属性来映射 Timestamp 列
设置为 Timestamp 的 Temporal

如图 11 所示,出生日期属性现在拥有了一个与其相关的注释。

图 11. Timestamp 关系性数据库列的注释
@Temporal(TIMESTAMP)
  1. 对于 Dependent JPA 实体的 birthdate 属性重复步骤 1–3,对于 Membership JPA 实体的 lastrenewaldatemembersince 属性,执行相同得操作。

注意:
Rational Application Developer 对 JPA 的工具提供了功能强大的实体与编辑器,降低了实体中编码注释,而被 EJB 和 JPA 规格所需要的知识。

将 Acme 的 JPA 实体调整为一对一,单向的关系

假设,为了反映 Acme 成员管理权的限制性因素,您可以对 JPA 实体做一些调整:

  1. 对于一些关系加强联系(从 多对一 改为 一对一
  2. 对于一些关系降低切换的灵活性(从双向转化为单向)

两种更改都将使得程序变得更加安全,并倾向更少地打破 Acme 成员程序业务规则的可能性。

更改关系的性质

  1. 打开 JPA PrimaryMember 实体。
  2. 在 Java 编辑器之中,选择 address 属性。
  3. JPA Details 视图之中,选择 many to one 超链接,如图 12 所示。
图 12. 更改关系的性质
Optional 未被选中,All 被选中了
  1. Mapping Type Selection 对话框窗口之中,选择 一对一,如图 13 所示,并点击 OK
图 13. Mapping Type Selection 对话框视图
界面截图之中一对一的箭头
  1. JPA Details 视图中,取消 Optional 复选框的选择,并选中 All 复选框,如图 12 所示。

在图 14 之中,注意关系的性质现在描述的是一对一。

图 14.注释指示是一对一的关系
@OneToOne
  1. 对于这些属性重复步骤 1:
    • Membership JPA 实体之中的 contactInfo 属性
    • Membership JPA 实体之中的 primarymember 属性

重点:
第 5 步与更改 JPA 实体关系本质的活动不相关。但是,它是让一个复杂的对象变得永久性所必需的步骤(例如,一个对象由一系列的实体及其他复杂的对象组成)。

  1. 对于 Membership JPA 实体,您可以选择 dependentCollection 属性,并在 JPA Details 视图之中,为 Cascade 选项而选择 All

更改关系切换选项

Acme 的成员管理程序并不需要 Address 对象访问包含的 PrimaryMember 对象。您可以按照下面的操作,来为该改进的限制性因素提供对象:

  1. 打开 Address 实体并删除 primaryMemberCollection 属性。
  2. 为 primaryMemberCollection 删除相应的 get 和 set 方法。
  3. 出于相同的原因考虑,为了限制其他的关系,您可以对 ContactInfo 实体中的 primarymemberCollection,以及 PrimaryMember 实体之中的 memberCollection 属性,重复步骤 1 和 2。

最终,在这些更改完成之后,您可以在 Problems 视图中看到一条警告信息,您可以通过删除掉未使用的导入来消除这条警告信息( 提示:Quick Fix 功能可以轻松地完成这项操作)。


运行 Acme 成员程序

现在您可以在 Rational Application Developer WebSphere 测试环境下部署 Acme 成员程序了。您可以使用 servlet 来运行 Acme 成员功能来创建一个新的家族成员。

  1. 确保您仍然停留在 JPA 视角下,然后从 Project Explorer 视图之中选择 AcmeMembershipApplicationDomain 项目。
  2. 右击并选择 JPA Tools > Configure Project for JDBC Deployment
  3. 在“为部署创建连接”对话框窗口之中,确保您在前面所创建的数据连接在 Connection 下列菜单中处于选中状态。
  4. 同样确保其他的复选框和值与图 15 中所示的相匹配。
  5. 然后点击 OK
图 15.“创建部署连接”的对话框
为 Connection 字段选择的 MEMBERS
  1. 从 JPA 视角切换回 Java EE 视角。
  2. Enterprise Explorer 视图之中,展开 AcmeMembershipApplicationWeb > Servlets
  3. 右击 CreateMembershipServlet 并选择 Run As > Run on Server
  4. 如果 Run On Server 对话框向导出现的话,那么在点击 Finish 之前,您可以选中 运行该项目时总使用该服务器 复选框(如图 16 所示)。
图 16. Run on Server 对话框
总是使用该服务器 … 选中
  1. 在 WebSphere Test Environment 服务器启动之后,它将会调用一个 servlet 并打开一个网络页面,指示创建一个新成员的成功。您将要查看数据库表格,以分析不同表格的值以确认创建操作。

总结

对于本文,我们使用 Rational Application Developer 工具来从一个拥有下列特征的 DB2 数据库中,快速创建并定制 JPA 实体:

  • 使用 DB2 Identity Value Generation 功能来创建独特主键值的表格
  • 一个表格之间非委琐的关系

通过使用 Rational Application Developer 环境,通过使用视图和编辑器,可以增加生产效率,这些视图和编辑器可以帮助您去编辑 JPA 实体,因此将您从手动给需要的注释编码中解放了出来。

最终,您可以使用 Rational Application Developer WebSphere 测试环境之中方便嵌入的 WebSphere Application Server,来运行您的程序。


致谢

作者感谢 Mike Reid 对本文所做全面而细致的评审工作。


下载

描述名字大小
本文的示例资源文件resources568.zip15KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational, WebSphere
ArticleID=588802
ArticleTitle=使用 Rational Application Developer,DB2 及 WebSphere Application Server 来自底向上创建 JPA 实体
publish-date=11222010