级别: 中级 刘 蕊 (ruiliu@cn.ibm.com), 高级工程师, IBM
2008 年 3 月 10 日 本文通过例子,介绍了如何在 WebSphere® 应用服务器提供的 Application Server Toolkit 开发环境中,开发一个简单的 EJB3.0 应用程序,并将它部署到包含 EJB 3.0 Feature Pack 的 WebSphere 应用服务器上去。
背景知识
EJB 3.0 规范被分为了 3 个子规范 :
- EJB 规范的体系结构
- EJB 3.0 简单 API
- Java 持久性 API (Java Persistence API)
其中,EJB 规范的体系结构定义了支持 EJB 标准的容器应该遵守的准则和要求;以及 Session Bean、Message-Driven Bean、事务、安全管理、部署描述符等功能需求和实现要求。
EJB3.0 简单 API 定义了基于 EJB 3.0 标准开发企业应用时所需要遵守的 Bean 类和接口要求,以及 EJB3.0 中除 Java Persistence API 部分之外的 EJB 实现所支持的注释(Annotation);此外还规定了 EJB 3.0 和此前的 EJB 规范如何同时工作。
EJB3.0 规范的最后一部分 Java Persistence API 是 EJB3.0 规范中变化最大的一部分,它被定义为用于管理持久性并实现 O-R Mapping 的子规范。
WebSphere 针对这部分子规范提供了自己的实现:WebSphere JPA (WSJPA),WSJPA 是基于 Apache 的开源项目 OpenJPA 实现的。OpenJPA 项目组织目前主要由来自于 BEA、IBM、Intel 的开发人员和一些个人组织组成。
从编程模型上看,标准的 JPA 编程模型将完全遵照规范规定,OpenJPA 的实现对规范做了一些扩展,而 WSJPA 则封装了 OpenJPA 的实现,同时,也做了相应的扩展。其中 WSJPA 的主要扩展集中于查询引擎领域。下图描述了 3 种不同的 JPA API 关系:
图 1. 三种不同的 JPA API 之间的关系
准备环境
确保 WebSphere 应用服务器安装了 Feature Pack for EJB 3
IBM 针对 WebSphere 应用服务器 V6.1 版本发布了针对 EJB3.0 规范的 Feature Pack。我们可以对现有安装的 WebSphere 应用服务器,安装 Feature Pack 升级包,根据图形向导,完成安装,将 WebSphere 应用服务器升级到包含 EJB 3 Feature Pack 的版本。安装完毕,运行 VersionInfo.bat 命令确认升级成功,如下图所示:
图 2. VersionInfo.bat 命令运行结果
准备 Application Server Toolkit (AST)开发环境
Application Server Toolkit (AST)是 WebSphere 应用服务器产品自带的基于 Eclipse 的开发工具,它完全支持基于 J2EE 规范的应用开发,为了支持 EJB3.0 应用的开发,我们需要安装 ASTV6.1.1 或以上的版本。下图所示为 AST 的版本信息。
图 3. AST 的版本信息
安装 AST 插件
在 AST 默认开发环境的基础上,我们可以增加额外支持 EJB3.0 开发的插件。这些插件往往可以帮助我们更容易地将 POJO 类型的 JAVA 实体 Bean 和关系型数据库表格实现映射,同时,也帮助我们生成 JPA 需要的 xml 配置文件。
当然,在熟悉 EJB 3.0 API 的情况下,您完全可以自己手工添加 XML 配置文件和基于 XDoclet 的注释代码。因为首先,EJB3.0 的 API 大大简化了;其次,AST 本身包含了对 XDoclet 基于注释的编程的支持,编写注释代码并不是一件痛苦的事情。但在本文中,为了简化并更清晰的描述整个开发过程,我们采用的是开源的 Dali 插件。Dali 插件的下载地址是:
http://www.eclipse.org/webtools/dali/downloads.php
安装完毕,我们将发现 AST 的开发环境中增加了一种新的视图 (Perspective): Java 持久性视图 (Java Persistence Perspective)。如下图所示:
图 4. 配置运行环境(1)
配置运行环境
我们必须将包含了 EJB 3 Feature Pack 的 WebSphere 应用服务器作为应用的运行环境。在 "windows->Preferences..." 窗口中,指定安装路径,将本地安装的 WebSphere 应用服务器添加到预定义的运行环境中。如下图所示:
图 5. 配置运行环境(2)
定义完毕,在 J2EE 视图的 server 窗口中,将定义好的运行环境添加进来,作为测试用的服务器。如下图所示:
图 6. 指定测试服务器
准备关系型数据库并配置数据源
在本文实验环境中,我们采用的是 DB2 数据库,在 DB2 数据库中创建了名为 Sample 的数据库和一个非常简单的 Customer 表格,表格中有 3 个字段: CustomerID,CustomerName 和 CustomerDiscription,并手工输入了一些实验数据。如下图所示:
图 7. Customer 表格字段
您可以在自己的实验环境中采用 WebSphere 应用服务器支持的任意关系型数据库创建同样的 Customer 表格。
我们在 WebSphere 应用服务器上创建名为 jdbc/Sample 的数据源,映射到该数据库上。如下图所示:
图 8. 在 WebSphere 管理控制台上配置数据源
如上图所示,无论您的环境中采用的是何种数据库,只要您在数据库中创建同样的 Customer 表格,然后在 WebSphere 应用服务器上将该数据库定义为 JNDI 名为 jdbc/sample 的数据源,并能够测试连接成功,您就可以继续跟随后面的过程,完成实验。
开发 EJB3.0 应用
我们将开发一个简单的实体 bean,然后通过 Web 应用访问这个实体 bean。
创建 J2EE 项目
首先,我们创建一个包含 Web 应用的 J2EE 企业级应用。如下图所示:
图 8. 创建包含 EJB3 的 J2EE 应用(1)
点击“Next”,进入下一步,填入 EJB3SampleEAR 作为应用名称,确保我们在 AST 开发环境中配置的包含 EJB Feature Pack 的 WAS 作为目标运行环境,如下图所示,点击“Next”,如下图所示:
图 10. 创建包含 EJB3 的 J2EE 应用(2)
如下图所示,在“New EAR Application Project”面板上,选择“New Module”,在弹出的“Create default J2EE modules”面板中,只选择“Web module”选项。如下图所示:
图 11. 创建包含 EJB3 的 J2EE 应用(3)
编写实体 bean
根据 JPA 规范,实体 bean 的代码将是普通的 pojo,因此,我们仅需要创建一个 J2EE Java Util 类型的项目,来放置我们的实体 Bean 代码,我们仅需要保证的是,这个实体 Bean 的 jar 包,将会运行在支持 JPA 规范的容器中,对于我们的环境来说,就是安装了 EJB Feature Pack 的 WebSphere 应用服务器。如下图所示:
图 12. 创建包含实体 Bean 的项目(1)
点击“Next”,如下图所示:
图 13. 创建包含实体 Bean 的项目(2)
将项目名称命名为“EJB3Entities”,并将该项目加入到之前创建的 J2EE 企业级项目“EJB3SampleEAR”中。点击“Finish”,完成创建。
项目创建完毕,我们开始编写实体 Bean POJO。在 EJB3Entities 项目点击右键,选择“New->Class”,创建一个名为 Customer 的实体类,如下图所示:
图 14. 创建 Customer 实体类
创建完毕,为 Customer 参照数据库表格的格式,创建 3 个 Field,并生成相应的 Getter 和 Setter 方法。这里需要注意的是,Field 名称和类型最好和表格列名一致(不区分大小写),因为 O-R Mapping 的过程中,默认情况下,当属性名称和表格列名一致的时候,您就不需要在额外的写 XDoclet 的注释来完成属性名和数据库表格列名之间的映射了。如下图所示:
图 15. 生成 Getter 和 Setter 方法
这一步完成之后,我们获得了一个简单的 Java Bean,它的属性名称和类型和一个数据库表格一一对应,下面,我们开始为这个 POJO 文件锦上添花,添加作为一个 EJB3 项目需要的 xml 配置文件以及相应的注释,使得它部署到容器中的时候,完成一个实体 bean 的使命。
右键点击 EJBEntities 项目,在“Java Persistence”选项下,选择“Add Java Persistence…”,如下图所示:
图 16. 使用插件添加 Java Persistence 需要的配置信息(1)
在弹出的窗口中,点击“Add connections”,如下图所示:
图 17. 使用插件添加 Java Persistence 需要的配置信息(2)
由于本文的数据库表格创建在 DB2 数据库中,在下图窗口中,我们选择了相应的数据库,给出了 JDBC Driver 需要的类库地址,填写连接数据库需要的参数,数据库访问的用户名密码,并点击“Test Connection”成功。最后,点击“Finish”完成 JPA 项目持久性数据连接的配置。如下图所示:
图 18. 配置 JPA 项目持久性数据连接
如下图所示,我们还需要选中相应的 Schema,然后,在“Packaging Settings”里面,填入持久性单元名称和实现类名。单元名称(Persistence unit name)在实体 bean Pojo 映射的注释代码中会引用,而“Persistence Provider”我们这里填写的是 IBM WebSphere 的实现,如前所述,WSJPA 完全封装了 OpenJPA,因此,这里您也可以填写 OpenJPA 的实现类。这些配置将定义在 persistence.xml 文件中,使得您的应用具备很好的可移植性。
- WASJPA 实现类:com.ibm.websphere.persistence.PersistenceProviderImpl
- OpenJPA 实现类:org.apache.openjpa.persistence.PersistenceProviderImpl
图 19. 配置 JPA 实现类
点击“Finish”完成配置。
下面,我们要在生成的 persistence.xml 文件中,添加声明,声明实体 bean 用到的 JDBC 数据源的 JNDI (即我们之前已经配置好的 JDBC 数据源);同时声明实体 Bean 的类文件。
persistence.xml 需要添加的内容
<jta-data-source>jdbc/sample</jta-data-source>
<non-jta-data-source>jdbc/sample</non-jta-data-source>
<class>com.ejb3sample.entities.Customer</class>
|
将以上几行添加到 persistence.xml 文件中,如下图所示:
图 20. 配置 persistence.xml 文件
下面我们要将 Customer 类和数据库中的 Customer 表格映射起来。首先,我们切换到 Java Persistence 视图,打开 Customer.java 文件,在右侧的 Persistence Outline 中,可以看到已经列出了 Customer 类的 Field,我们要做的,是依次选中它,和数据库表格以及表格中的列进行映射。如下图所示:
图 21. 生成持久性映射(1)
在 Persistence Outline 中,选中 Customer,在右下角的 Persistence Properties 中,选择 Map As Entity,这样,我们看到,默认情况下,Customer 类将和数据库中名为 Customer 的表格映射起来。如果您的类名和数据库表名不同,您也可以在下拉菜单中选择表名,那么相应的表名将以注释的方式添加到 Customer.java 文件中。如下图所示:
图 22. 生成持久性映射(2)
这时,“Problems”窗口中提示:“Entity does not have an Id”,因此,我们需要把 CustomerId 映射为表格的主键。选中“Persistence Outline”窗口中的“CustomerId”,在右下方“Persistence Properties”窗口中将其映射为表格的主键列。如下图所示:
图 23. 生成持久性映射(3)
完成映射,保存修改,错误消失。
由于我们的 DB2 数据库中有多个 Schema,因此需要在 @Entity 下面添加如下注释,以定位 Customer 表格:
@Table(Schema=”SAMPLE” name=”CUSTOMER”),如下图所示:
图 24. 生成持久性映射(4)
这样,我们就完成了 Entity bean 的编写工作。如果您的字段名称和数据库列名不同,在这一步中,还需要在“Persistence Properties”窗口中分别映射各个字段。
编写 SQLJ
下面,我们将在 Entitiy Bean 的 POJO 中,添加一个 SQLJ 的查询。关于 SQLJ 的语法和使用,不是本文的重点,这里,我们仅把一个非常简单的 SQLJ 的查询添加的 Customer.java 的开头部分。
Customer.java 中的 SQLJ
@NamedQueries ( {
@NamedQuery (
name = "getCustomerNameById",
query = "select c.CustomerName from Customer c where c.CustomerId= :id"
)
})
|
对于引入的错误,我们将通过导入 javax.persistence.NamedQueries 和 javax.persistence.NamedQuery 类解决,如下图所示:
图 25. 编写 SQLJ 代码
编写 Web 客户端访问实体 bean
在创建访问 EJB 项目的 Servlet 之前,我们先声明 Web 项目对实体 Bean 项目的引用关系,在 EJB3SampleEARWeb 项目的属性选项中,选择“J2EE Module Dependency”,在 J2EE Modules 标签中,复选“EJB3Entities.jar”包。如下图所示:
图 26. 定义访问 EJB 的 Web 客户端属性
下面,在 EJB3SampleEARWeb 项目中创建名为 EJB3ServletClient 的 Servlet,如下图所示:
图 27. 编写名为 EJB3ServletClient 的 servlet 访问 EJB 项目
点击“Finish”完成创建。
在 EJB3ServletClient 中,声明 EntityManager。代码如下:
声明 EntityManager
@PersistenceContext(unitName="MYJPA")
private static EntityManager em;
|
导入 javax.persistence.EntityManager 和 javax.persistence.PersistenceContext 类,消除编译错误。
在 doGet 方法中加入以下代码:
doGet 方法中加入的代码
Query query = em.createNamedQuery( "getCustomerNameById" );
query.setParameter("id", 1);
System.out.println( "get customer name from servlet: "+(String)query.getSingleResult());
|
部署和验证应用
切换至“J2EE Perspective”视图,在“Servers”窗口中,启动之前创建好的 WAS 运行环境,右键选中 server,选择“Add and Remove Projects…”,将 EJB3SampleEAR 添加到运行环境中。如下图所示:
图 27. 添加项目至测试环境
点击“Finish”完成部署。
右键点击 EJB3ServletClient.java,选择“Run on Server”,如下图所示,选择 WebSphere 应用服务器为运行环境,运行。
图 29. 运行 EJB3ServletClient
我们在 console 窗口中,可以观察到运行结果,如下图所示:
图 30. 运行结果
这样,我们就通过 Servlet 访问实体 Bean,执行查询,将 Id 为 1 的用户姓名查询出来,并输出到控制台上。
总结
本文中,我们回顾了 EJB3.0 规范的组成和 IBM WebSphere 应用服务器对 EJB3.0 的实现,然后通过一个简单的实体 bean 的例子,体验了使用 WebSphere 应用服务器自带的 AST 开发工具开发 EJB3 应用的例子,并演示了通过 Web 应用客户端访问 EJB3 的持久 Bean 的过程。
通过本文,并学习链接中的网站,希望您可以基于 WebSphere 应用服务器产品,着手开始编写自己的 EJB3 应用,并进行扩展,结合 JAVA EE 5 的编程模式 (Patterns),得到移植性强,性能优秀,易于维护的企业级应用。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 文中例子的项目交换文件 | EJB3Sample.zip | 13KB | HTTP |
|---|
参考资料 学习
获得产品和技术
讨论
关于作者  | |  | 刘蕊是IBM软件部的工程师,主要负责WebSphere应用服务器以及开发工具的技术工作。您可以通过ruiliu@cn.ibm.com同她取得联系。 |
对本文的评价
|