首页 > Linux操作系统 > Linux操作系统 > [转载]有效的实体 EJB 开发
随着越来越多的程序员在其项目中使用 Enterprise JavaBean (EJB) 组件,对简化 EJB 开发的工具需求也日渐增长。本文讨论容器管理的持久性 (CMP) 实体 Enterprise JavaBean,并介绍用于创建这种 JavaBean 的免费工具。
容器管理的持久性 (CMP) 实体 Enterprise JavaBean 本质上是持久数据的封装器(通常以关系数据库表形式),另外还支持事务控制和安全性。CMP 实体 bean 至少从六个单独文件构造,并有在编译期间无法方便验证的相关性。必须注意确保对象到关系数据库映射的正确性,理想情况下,应该将代码设计成在需求变更时所 需的更改最小。本文描述在编写大型 EJB 项目时面临的某些挑战,以及如何通过可从 IBM alphaWorks Web 站点(请参阅 参考资料)下载的 EJBMaker 工具克服这些问题。
EJBMaker 读取一个 CMP EJB 描述文件(用 XML 编写),然后自动生成 Java 源代码和数据库脚本。该工具负责 bean 的 finder 和初始化方法的烦琐定义,并能够生成使 CMP EJB 相互关联的关系 EJB。EJBMaker 跟踪 XML bean 描述符文件中的更新,并只对已更改的 EJB 重新生成 Java 代码。另外还生成 adaptor 类以允许快速初始化以及从使用 XML 的 EJB 抽取数据。EJBMaker 与 IBM WebSphere 应用服务器一起使用时性能最优,但经过一些手工调整,也可以与其它应用服务器一起使用。
EJB 技术的优势之一在于(至少在理论上),EJB 只编写一次就可以在任何遵循 EJB 的应用服务器上运行。规范的 2.0 版包含了如 EJB 查询语言等的技术,带领我们朝这个目标更进一步。
虽 然还没有实现“编写一次,到处运行”的承诺,但是 EJB 可以十分方便地从一个应用服务器环境移植到另一个 -- 特别是容器管理的持久性 (CMP) 实体 EJB 更是如此。在编写 CMP 实体 EJB 时,开发人员不必担心有关数据库中持久存储 bean 状态的编码。在部署阶段,所有这些代码都在应用服务器上自动生成。这会使 bean 的灵活性有所降低,但另一方面,却可以进行更快速的开发。应用服务器设计者可以自由使用任何设计成持久存储和检索 EJB 数据的方法,只要这些方法遵守“容器管理的持久性实体 bean 组件契约”即可,由 EJB 规范定义(请参阅 参考资料)。目前为止,最常见的解决方案是使用 Java 数据库连接 API (JDBC) 将数据存储在关系数据库中(有关 JDBC 的信息,请参阅 参考资料)。这是 IBM WebSphere 应用服务器和 BEA WebLogic(以及其它服务器)使用的技术。
另 一种实体 EJB 类型是 Bean 管理的持久性 (BMP) EJB。在这种情况下,开发人员负责手工编写代码来持久地检索或存储 bean 信息。当需要将数据存储在旧有存储系统或文件系统中时,BMP 是理想的。然而,灵活性增加是以可移植性降低为代价的。当应用服务器不在控制所有对系统资源的访问时,无法保证这些资源在不同服务器环境中的存在和兼容 性。
|
除非确实有强制 BMP 实现的特定需求,否则 CMP 是更好的选择。如何编写 CMP bean 呢?需要创建以下文件:
|
除了确保所有上述文件都存在之外,开发人员在编写 CMP 实体 bean 时还要避免几个缺陷。首先,文件之间存在相关性,但无法在编译期间进行验证。
其它需求包括:
看 过所有这些需求之后您可能会想,编写 CMP 实体 bean 可能不适合于意志薄弱者。幸运的是,有一些工具将辅助您完成这些步骤中的很多步。例如,IBM VisualAge for Java IDE 包含一个极好的 EJB 开发环境,该环境将为您自动生成许多必需的代码,甚至可以帮助您进行对象到关系数据库的映射。BEA Systems 的 WebGain Studio和 WebGain StructureBuilder通过自动将 UML 模型转换成 EJB 组件等来帮助开发人员处理某些更棘手的 EJB 开发任务。但是如果不能自由切换 IDE 该怎么办呢?那种情况会很麻烦,除非...
|
为 帮助解决某些与 CMP bean 相关的棘手问题,创建了 EJBMaker 工具。虽然该工具生成的是特定于 WebSphere 的文件,但是修改用于其它环境的输出却相当简便。所有与 CMP bean 相关的信息(包括 bean 名称、持久字段名称和类以及关系数据库映射)都存储在一个文件中。该文件的格式是很灵活并易于为 EJBMaker 未来版本扩展的 XML。
从该 EJBMaker XML 文件生成以下内容(请参考前面的 “CMP bean 剖析”):
将自动照管所有相关性,包括对象到关系数据库映射。生成缺省的 finder 方法来检索与 bean 中每个持久字段值匹配的实例,并检索所有现有的 bean 实例( getAllInstances() 方法)。这确保 bean 足够灵活以在很多不同方案中使用。如果需要特殊的 finder 方法,可以直接在 XML 描述文件中输入。
下面是以 EJBMaker XML 格式描述的一个 CMP bean 示例:
|
该文件有几部分。 transaction-attr 、 isolation-level 、 run-as-mode 和 re-entrant 直接取自 Sun 的 XML EJB 部署描述符格式。这些 bean 属性作为所有 bean 的缺省属性复制到生成的部署描述符。
在那以后遇到的第一个元素是:
这是新 bean 声明的开始。该 bean 的 Java 命名与目录接口 (JNDI) 名称是 'Account',类型是 'entity'。EJBMaker 目前只支持 'entity' bean 类型。
下几行指明如何标识持久字段:
|
在 Account bean 中定义的第一个持久字段是 ACCTNUMBER。用于存储该持久字段的 Java 类是原始的 int 类(由 dt 属性声明),用作为 INTEGER 的 col_dt 属性声明该数据库列的数据类型。还多定义两个持久字段 SSN 和 BALANCE。
下几行指明如何指定特殊 finder 方法:
|
finder 方法的名称是 findNegativeAcct。请注意,位于元素中的 SQL 代码必须符合 XML 内容规则。特别地,这意味着必须避免如小于号等保留 XML 字符。
向 EJBMaker 传递 XML 文件将生成源代码、XML 部署描述符和数据库脚本。
|
从上例可生成以下 Java 类和方法:
某些方法需要进一步解释。远程接口 ( Account.java ) 和远程接口实现 ( AccountBean.java ) 有一个名为 getKey() 的方法。该方法只返回 bean 的主键作为 String 实例,而不是由其超类的 getPrimaryKey() 方法返回作为 AccountKey 实例。
远程接口和远程实现类还有 initialize(TXDocument) 和 getXML() 方法。这两个方法用来使用 XML 快速初始化 bean,以及抽取以 XML 形式存储在 bean 中的信息。有关如何使用这两个方法的信息,请查看此 示例。
这段代码还解释了如何使用 AccountXMLAdaptor 类。它是 Account XML 文档的封装器,并包含设置与获取与 Account 相关特性的方法。请注意,原始 Java 类的持久字段被转换成 adaptor 中对等的非原始类。按这种方式,就可以使用空值来表示 未初始化 状态,这对只设置持久字段的子集很有用。使用 adaptor 类的 getXML() 方法以 XML 形式编码所有与 Account 相关的信息。XML 格式很简单,根元素总是 EJB 名称, 对于每个持久字段包括一个元素。在 Account 示例中,可以将 EJB 实例序列化成以下 XML 文档:
|
|
EJBMaker 还可以生成用来表示 bean 之间多对多关系的 EJB。例如,考虑一个简单的日程应用。使用两个 CMP 实体 bean,一个包含有关日程活动(称为 Event)的信息,另一个包含有关日程应用客户(称为 Client 的信息)。现在要表示参加特定日程活动的客户。一种原始的解决方案是向 Event bean 添加一个包含所有参加特定活动的客户主键的字段。可以使用分隔符(例如逗号)来并置主键。要检索所有参加活动的客户,必须编写代码来接受用逗号分隔的主键 字符串,并使用 Client 接口中的 findByPrimaryKey(...) 对每个键进行查询。即使在会话 bean 中编写代码,与第二种解决方案相比性能是缓慢的。
更好的解决方案是使用另一个表来表示事件和客户之间的关系。两个列包含 Event EJB 实例和 Client EJB 实例的主键。现在,检索所有参与活动的客户的任务只是在 Client 宿主接口中编写 finder 方法和在 helper finder 类中编写 SQL 查询。这正是 EJBMaker 要做的。使用以下技术构造两个 bean 之间的关系:
|
用 名为 Attendee 的新 CMP 实体 bean 表示关系,该 bean 有两个字段(如果加上主键字段则有三个)。这两个字段包含 Event EJB 和 Client EJB 的主键实例。另外,还创建了两个附加的 finder 方法,一个位于 Event 宿主接口,另一个位于 Client 宿主接口。Event 宿主接口 finder 方法是:
java.util.Enumeration findByAttendee(String pkey) |
'pkey' 是 Client EJB 的主键。该方法返回特定客户参加的活动的枚举列表。客户宿主接口有同样的方法:
java.util.Enumeration findByAttendee(String pkey) |
然而在该类中,'pkey' 是 Event EJB 的主键,该方法返回参加特定活动的客户的枚举列表。
|
EJBMaker 生成的代码的最后一部分是用来创建持久 EJB 表的数据库脚本。除了创建所有必需表的 CreateTables.ddl 脚本之外,还要为每个 EJB 创建一个脚本。然而,在创建虚表(或视图)之前,应用服务器不能使用表。视图改变表中的列顺序,以便这些列与生成的 EJB 持久性代码所期望的顺序相对应。EJBMaker 中有一个工具可以为您生成 CreateViews.ddl 脚本。必须在每次部署 EJB 时生成该脚本,否则列顺序可能会出错。通过在应用服务器和物理数据库表之间使用视图抽象,即使重新部署 EJB,也可以使信息存储在持久性表中。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/374079/viewspace-130483/ ,如需转载,请注明出处,否则将追究法律责任。