使用WebSphere Application Server Community Edition开发JPA应用程序

JPA是用于管理持久性和对象/关系映射的Java API。 它可在Java EE 5环境和独立Java SE环境中使用。 它使用Java域模型提供对象/关系映射工具,以管理关系数据库。 它使用Java批注或XML文件配置来启用基于POJO的编程模型。

JPA提供了标准的映射定义(通过注释或XML)以及标准的运行时API和对象级查询语言(JPQL)。 JPA是EJB规范和Java EE 5平台的一部分,但也可以在Java SE环境中使用。 Enterprise JavaBeans 3.0支持持久性API和查询语言。 JPA规范正在Java Community Process Program下作为JSR-220的一部分制定。

JPA大大减少了开发应用程序持久性部分所需的编程工作量,因为它允许基于POJO的Java对象编程模型,并将复杂的样板代码与应用程序逻辑分离。 通过JDBC™API连接到RDBMS数据存储的Java应用程序要求您开发大量代码,以进行连接管理,事务管理,查询以及通过结果集进行数据检索。 通常,所有这些代码都与应用程序逻辑交织在一起,从而使应用程序维护很麻烦。 使用JPA,所有这些样板代码都通过批注或XML文件委派给JPA提供程序,从而保留了干净的应用程序逻辑。 JPA提供:

  • 标准映射定义(通过注释或XML)
  • 标准运行时API
  • 对象级查询语言(JPQL)

WebSphere Application Server社区版v2.1是基于Apache Geronimo v2.1发行的轻量级应用程序服务器。 此后,在本教程中,WebSphere Application Server社区版v2.1简称为社区版。 Community Edition还包括许多其他缺陷修复程序,并从IBM获得了世界一流的支持。 您可以免费下载服务器的二进制映像。 它是Java EE 5 Apache Geronimo v2.1的完全认证服务器,因此Community Edition将OpenJPA用于其JPA实现。

OpenJPA是Apache Software Foundation的Java EE持久性项目。 它是Enterprise Java Beans 3.0规范的持久性部分的开源实现。 它提供了JPA的功能丰富的实现,该实现可以用作独立的POJO持久层,也可以集成到任何符合EJB 3.0的容器中。 它的许多自定义配置意味着您可以轻松地在许多轻量级框架中使用它。

在本教程中

本教程向您展示如何在旨在在Community Edition上运行的Java EE 5应用程序中使用JPA。 在开发Web应用程序时,我们将说明JPA的各个方面。 我们将Eclipse集成开发环境(IDE)与Eclipse的Community Edition插件(也称为Web工具平台(WTP)服务器适配器)一起使用,以开发,部署和运行该应用程序。 本教程适用于希望快速学习如何将JPA用作其应用程序的持久层的开发人员。 本教程包括以下部分:

先决条件

您应该了解数据库概念,并且应该对Java编程非常熟练。 了解Java EE 5的概念和注释将帮助您理解本教程的内容。 您应该具有使用像Eclipse这样的IDE的经验。 由于我们将手动修改XML配置文件(我们进行一些徒手编程!),因此必不可少的知识是如何为应用程序服务器编写部署计划。

系统要求

要开发,部署和运行该应用程序,需要以下环境:

  • IBM Java SDK v1.5.0 SR7或更高版本
  • 带有WTP v2.0.1的Eclipse v3.3.1
  • 适用于Community Edition v2.1的WTP服务器适配器
  • 社区版v2.1
  • DB2 Express v9.5

我们将使用两个数据库; DB2-Express v9.5中运行的SAMPLE数据库和Community Edition中嵌入的Derby数据库中运行的ACCOUNTDB 。 我们使用SAMPLE数据库说明了使用JPA进行的本地事务,但是我们同时使用了这两个数据库来说明JTA事务。

持续时间

2小时

在Eclipse IDE中创建JPA项目,并生成持久类

在本节中,我们将执行以下任务。

  • 安装社区版v2.1
  • 设置Eclipse开发环境
  • 设置Derby数据库
  • 设置DB2 Express数据库
  • 在Eclipse IDE中设置数据源
  • 创建Db2AccountUnit JPA项目
  • 创建DerbyAccountUnit JPA项目

安装社区版v2.1

可以从developerWorks下载Community Edition v2.1安装程序(请参阅参考资料)。 将服务器下载到您的计算机中,并按照Community Edition v2.1文档中的说明进行操作 。 在本教程中,我们将Community Edition安装目录称为<wasce_home> 。 Community Edition安装程序随IBM Java SDK1.5.0一起提供。 安装程序和服务器运行时都使用JDK。 有关推荐和兼容平台的更多信息,请访问支持网站。

设置Eclipse开发环境

请访问Community Edition v2.1文档,单击左侧的“ 开发”链接以查看有关常见开发任务的部分。 遵循“ 使用Eclipse”部分中给出的指示信息,在本地计算机上为Community Edition设置Eclipse开发环境。 您可以使用Eclipse更新管理器来下载和安装Community Edition Eclipse插件。 或下载deployable.zip然后将zip文件内容覆盖到Eclipse目录中。

浏览文档的其他部分,以了解如何在Eclipse中创建Community Edition服务器实例,将Java EE5资产部署到该服务器上,等等。在Eclipse中创建一个Community Edition服务器实例,指向安装在<wasce_home>的服务器。目录。 在此任务结束时,您应该在Eclipse中创建Community Edition服务器实例,如图1所示:

图1. Eclipse中的Community Edition服务器
屏幕快照显示了Eclipse中的Community Edition服务器
设置Derby数据库

在本节中,我们在Derby中创建ACCOUNTDB数据库。 我们还为应用程序创建了DERBYACCOUNT表,其中包含一些示例行。 我们将使用Community Edition Web管理控制台执行此任务。

  1. 打开命令窗口并提交以下命令以启动服务器: <wasce_home>/bin/startup.[bat|sh]
  2. 打开浏览器窗口,然后输入以下URL以打开管理控制台: http://localhost:8080/console.
  3. 输入system作为用户名,输入manager作为密码,以登录Web控制台。
  4. 在控制台导航portlet上,选择Embedded DB => DB Manager打开DB Viewer并运行SQL portlet。
  5. Create DB字段中,输入AccountDB并单击Create按钮,如图2所示。 此步骤将创建AccountDB数据库。 数据库文件的位置是<wasce_home>/var/derby/AccountDB
    图2.创建一个数据库
    该屏幕快照显示了如何创建数据库
  6. 在“ 使用数据库”字段中,选择AccountDB数据库,然后在“ SQL命令”字段中输入以下SQL语句:
    create table DERBYACCOUNT (ACCNO integer, OWNER varchar(100), DATE_OPEN date, 
    ACCOUNT_TYPE varchar(20), BALANCE decimal(15,2));
  7. 单击“ 运行SQL”按钮以创建DERBYACCOUNT表。
  8. 在“ 使用数据库”字段中,选择AccountDB数据库,然后在“ SQL命令”字段中输入以下SQL语句:
    insert into DERBYACCOUNT values (1, 'Jane', '10/10/2008', 'SAVINGS', 10000);
    insert into DERBYACCOUNT values (2, 'Monica', '10/10/2008', 'CHECKING', 20000);
  9. 单击“ 运行SQL”按钮,将两行插入DERBYACCOUNT表。
  10. 最终表和插入的行应类似于图3:
    图3.插入行的表
    具有插入行的表的屏幕截图

设置DB2 Express数据库

在本节中,我们在DB2中运行的SAMPLE数据库中创建DB2ACCOUNT表。 您可以使用DB2控制中心或DB2命令提示符来执行此任务。 确保您已经创建了DB2用户帐户DB2ADMIN并为其授予了足够的特权来访问数据库。

  1. 在您的机器上安装DB2 Express v9.5。 默认情况下,安装过程将创建SAMPLE数据库。
  2. 使用control-center或DB2命令提示符,使用清单1中所示的列定义创建DB2ACCOUNT表。

    清单1:D2CACCOUNT表列定义

    CREATE TABLE "DB2ADMIN"."DB2ACCOUNT" (
    "ACCNO" INTEGER NOT NULL ,  "OWNER" VARCHAR(100) NOT NULL ,  
    "DATE_OPEN" DATE NOT NULL ,  "ACCOUNT_TYPE" VARCHAR(20) NOT NULL ,
     "BALANCE" DECIMAL(15,2) NOT NULL ) ALTER TABLE "DB2ADMIN".
    "DB2ACCOUNT" ADD CONSTRAINT "DB2ACCOUNT_PRIMARYKEY"
    PRIMARY KEY ("ACCNO");

    我们将开发一个Web应用程序,以使用JPA对上表执行数据操作操作(DML)操作。
  3. 最终表应类似于图4:
    图4.最终表
    屏幕快照显示了决赛桌

在Eclipse IDE中设置数据源

在本部分中,我们将在Eclipse中创建WASCEDerbyDB2数据源。 该WASCEDerby数据源连接到ACCOUNTDB在嵌入式Derby实例创建的数据库。 DB2数据源连接到DB2数据库中的SAMPLE数据库。 您可以将这些数据源与JPA项目相关联,以为基础表生成持久类。

  1. 使用以下命令关闭Community Edition服务器:。
    <wasce_home>/bin>shutdown.[bat|sh] –user system –password manager
  2. 单击Eclipse中的Data Source Explorer选项卡,右键单击Databases并单击New ,如图5所示:
    图5.在Eclipse中创建一个新的数据源
    该屏幕截图显示了如何创建新的数据源
  3. 在“ 新建连接配置文件”向导上,选择“ Derby嵌入式数据库” ,然后单击“ 下一步”按钮,如图6所示:
    图6.新的连接配置文件wizart
    选择Derby嵌入式数据库的屏幕截图
  4. Derby Embedded Database向导上,提供WASCEDerby作为Name,并为Description(可选)提供任何描述,如图7所示,然后单击Next按钮。
    图7. Derby嵌入式数据库向导
    Derby嵌入式数据库向导的值的屏幕快照
  5. 在“ 指定驱动程序和连接详细信息”向导上,单击从下拉框中选择驱动程序右侧的按钮以配置驱动程序(图8):
    图8.驱动程序和连接详细信息向导
    驱动程序和连接详细信息向导的值的屏幕快照
  6. 在“ 驱动程序定义”向导中,选择10.2 ,然后单击“ 添加”按钮。
    图9.驱动程序定义向导
    驱动程序定义向导的值的屏幕快照
  7. 在“ 新驱动程序定义”向导中; 选择“ Derby Embedded JDBC驱动程序”,然后选中“ 立即编辑新驱动程序定义”框。 单击确定按钮。
    图10.新建驱动程序定义向导
    “新驱动程序定义”向导的值的屏幕快照
  8. 在“ 编辑驱动程序详细信息”向导中,执行以下步骤:
    • 从“ 驱动程序文件”框中删除所有现有的JAR文件,然后添加以下JAR文件:< wasce_home>repository/org/apache/derby/derby/10.2.2.0/derby-10.2.2.0.jar
    • 如下所示在Properties框中更改Connection URLDatabase NameUser ID (也如图11所示)。 请注意, C:\ibm\wasce-server-2.1.0.0是我的本地系统上的<wasce_home> 。 单击确定
    连接网址 jdbc:derby:C:\ ibm \ wasce-server-2.1.0.0 \ var \ derby \ AccountDB
    数据库名称 帐号数据库
    用户身份 应用程式

    图11. Edit Driver Details向导
    “编辑驱动程序详细信息”向导的值的屏幕快照
  9. 通过单击“ 确定”继续关闭所有打开的向导直到“ 指定驱动程序和连接详细信息”向导出现在最前面。 单击Next按钮,然后在下一个屏幕上单击Finish按钮,如图12所示:
    图12.指定驱动程序和连接详细信息向导
    “指定驱动程序和连接详细信息”向导的值的屏幕快照
  10. 这将创建WASCEDerby数据源。 同样,我们需要遵循相同的步骤在Eclipse中创建DB2 sata源。 在为DB2创建数据源时,将数据库名称设置为SAMPLE并选择以下驱动程序库(<db2_home>是DB2 v9.5 Express的安装目录):
    • <db2_home>/java/db2jcc.jar
    • <db2_home>/java/db2jcc_license_cu.jar
  11. 最后,输入以下DB2数据源连接详细信息(也如图13所示):
    名称 DB2
    描述 DB2
    自动连接
    司机姓名 IBM DB2通用
    用户名 DB2ADMIN
    网址 jdbc:db2:// localhost:50000 / SAMPLE

    图13. DB2数据源连接详细信息
    DB2数据源连接详细信息的屏幕快照
  12. 右键单击每个创建的数据源,然后单击“ 连接”以连接到SAMPLEACCOUNTDB数据库(图14):

    要点:使用嵌入式驱动程序从Eclipse连接到ACCOUNTDB数据库时,必须关闭Community Edition服务器。 如果服务器正在运行,并且使用嵌入式驱动程序连接到该数据库,那么当您尝试连接到同一数据库时,Eclipse将引发错误。

    图14.连接到数据源
    连接到数据源的屏幕截图

创建Db2AccountUnit JPA项目

JPA项目创建一个持久性单元。 持久性单元是一组可管理的持久性类以及部署描述符。 部署描述符文件是persistence.xml 。 Eclipse使您可以将JPA项目与数据源相关联,并从基础表生成持久实体类。 它提供了各种选项来通过向导配置持久性单元。

在本节中,我们将创建Db2AccountUnit JPA项目,并将其与我们之前创建的DB2数据源相关联。 我们还将为DB2ACCOUNT表生成一个持久类。

  1. 右键单击Project Explorer ,然后导航到New => Other (图15):
    图15.导航到New-Other
    菜单选择的屏幕截图
  2. 在下一个向导上,选择“ JPA => JPA Project” ,然后单击“ 下一步”按钮。
    图16.选择JPA项目
    选择JPA项目的屏幕截图
  3. JPA Project向导中,输入下表中各个字段的值(也如图17所示)。 单击下一步按钮。 我们正在创建一个DB2AccountUnit JPA项目,该项目连接到DB2中运行的SAMPLE数据库。 JPA项目将能够为SAMPLE数据库中创建的表生成Java持久类。
    项目名称 DB2AccountUnit
    目标运行时间 IBM Community Edition v2.1
    构型 IBM Community Edition v2.1的缺省配置

    图17. JPA向导
    JPA向导的值的屏幕快照
  4. Project Facets向导上,检查所有Project Facets ,然后单击Next按钮(图18):
    图18. Project Facets向导
    “ Project Facets”向导的值的屏幕快照
  5. Geronimo Deployment Plan向导上,提供下表中的值(也显示在图19中),然后单击Next按钮。
    群组编号 网路
    工件ID 帐户JPA-DB2
    1.0
    神器类型 汽车

    图19. Geronimo部署计划向导
    Geronimo部署计划向导的值的屏幕快照
  6. JPA Facet向导上 ,选择下表中的值(也显示在图20中),然后单击Finish按钮。 此步骤将创建DB2AccountUnit JPA项目。 它还在META-INF文件夹中创建persistence.xml 。 我们可以在以后编辑此文件以配置持久性单元。
    平台 泛型
    连接 DB2
    JPA实施 使用服务器运行时提供的实现
    持续的班级管理 自动发现带注释的类
    创建orm.xml 取消选中该复选框
    图20. JPA Facet向导向导
    JPA Facet向导向导的值的屏幕快照
  7. 右键单击DB2AccountUnit项目,然后导航到JPA Tools => Generate Entities ,如图21所示:
    图21.打开Generate Entitites向导
    该屏幕快照显示了如何打开“生成实体”向导
  8. Generate Entities向导上,提供数据库设置值作为DB2DB2ADMIN ,然后单击Next按钮(图22):
    图22.生成实体向导
    该屏幕快照显示了Generate Entitites向导
  9. 在“ 从表生成实体”向导中,选择DB2ACCOUNT表,然后为该包输入sample.jpa ,如图23所示。 单击完成按钮。 此步骤在DB2AccountUnit项目中生成sample.jpa.Db2account类。 此类使用JPA注释进行了完全注释,并且对应于SAMPLE数据库中的DB2ACCOUNT表。
    图23.从Tables向导生成实体
    该屏幕快照显示了从表向导生成实体

    图24显示了Db2account.java源文件:

    图24. Db2account.java
    屏幕截图显示了Db2account.java

创建DerbyAccountUnit JPA项目

在本节中,我们将创建DerbyAccountUnit JPA项目,并将其与我们之前创建的WASCEDerby数据源相关联。 我们还将为DERBYACCOUNT表生成一个持久类。 我们将按照上一节中的步骤创建项目:

  1. 右键单击Project Explorer ,然后导航到New => Other
    图25.导航到JPA项目
    该屏幕截图显示了如何导航到JPA项目
  1. 在下一个向导中,选择“ JPA => JPA Project” ,然后单击“ 下一步”按钮。
    图26.打开JPA项目向导
    该屏幕截图显示了如何打开JPA项目向导
  2. 这将打开“ JPA项目”向导。 提供下表中给出的值(如图27所示),然后单击Next按钮。 我们正在创建DerbyAccountUnit JPA项目,该项目连接到在嵌入式Derby数据库中运行的AccountDB数据库。 JPA项目将能够为AccountDB数据库中创建的表生成Java持久类。
    项目名称 德比帐户单位
    目标运行时间 IBM WASCE v2.1
    构型 IBM WASCE v2.1的默认配置

    图27. JPA项目向导
    屏幕快照显示了JPA项目向导
  3. 项目构面向导中,检查所有项目构面 ,然后单击下一步按钮。
    图28. Project Facets向导
    屏幕快照显示了Project Facets向导
  4. Geronimo Deployment Plan向导上,提供下表中给出的值(也显示在图29中),​​然后单击Next按钮。
    群组编号 网路
    工件ID 帐户JPA-Derby
    1.0
    神器类型 汽车

    图29. Geronimo部署计划向导
    屏幕快照显示了Geronimo部署计划向导
  5. JPA Facet向导上,选择下表和图30中所示的值,然后单击Finish按钮。 此步骤将创建DerbyAccountUnit JPA项目。 它还会在META-INF文件夹中创建一个persistence.xml文件。 我们可以在以后编辑此文件以配置持久性单元。
    平台 泛型
    连接 WASCED比
    JPA实施 使用服务器运行时提供的实现
    持续的班级管理 自动发现带注释的类
    创建orm.xml 取消选中该复选框

    图30. JPA Facet向导
    屏幕快照显示了JPA Facet向导
  6. 右键单击DerbyAccountUnit项目,然后导航到JPA Tools => Generate Entities
    图31.打开Generate Entities向导
    该屏幕截图显示了如何打开“生成实体”向导
  7. 在“ 生成实体”向导上,提供WASCEDerbyAPP的“数据库设置”值,然后单击“ 下一步”按钮。
    图32.生成实体向导
    该屏幕快照显示了“生成实体”向导
  8. 在“ 从表生成实体”向导上,选择DERBYACCOUNT表,为包提供sample.jpa ,然后单击“ 完成”按钮。 此步骤在DerbyAccountUnit项目中生成sample.jpa.Derbyaccount类。 此类使用JPA注释完全注释,并且对应于AccountDB数据库中的DERBYACCOUNT表。
    图33.从Tables向导生成实体
    该屏幕快照显示了“从表生成实体”向导

    图34显示了Derbyaccount.java源文件:

    图34. Derbyaccount.java
    屏幕快照显示Derbyaccount.java
  9. JPA项目DB2AccountUnitDerbyAccountUnit是独立的持久性单元。 您可以将它们导出为JAR文件并将其嵌入到任何JEE模块(WAR,EJB,EAR)中。 您可以通过相应的persistence.xml文件独立配置每个持久性单元。

使用persistence.xml配置持久性单元

在本节中,我们执行以下任务:

  • 探索持久性上下文,实体经理和实体经理工厂
  • 配置DB2AccountUnit持久性单元
  • 在Community Edition中部署DB2Datasource数据库连接池
  • 配置DerbyAccountUnit持久性单元

探索持久性上下文,实体经理和实体经理工厂

persistence.xml文件描述了持久性单元。 使用JPA时,它是用于持久性的部署描述符文件。 您使用它来声明:

  • 托管持久性类
    例如,托管类是使用@Entity, @Embeddable @MappedSuperclass @Entity, @Embeddable@MappedSuperclass进行注释的@MappedSuperclass
  • 对象/关系映射
    JPA提供了几种将Java类映射到关系数据库中的表的机制。
  • 配置信息
    对于实体经理和实体经理工厂类。

实体管理器在持久性上下文中进行工作。 持久性上下文是一组管理实体实例,其中对于任何持久性实体标识,都有一个唯一的实体实例。 实体身份使用主键进行管理。

实体管理器有两种类型,具体取决于您如何管理持久性上下文: 容器管理的实体管理器和应用程序管理的实体管理器。 容器管理的实体管理器是其持久性上下文由容器管理的实体管理器。 您可以使用@PersistenceContext批注来获得容器管理的实体管理器。 此注释使容器将实体管理器对象注入到引用中。 它传播实体管理器的持久性上下文以及当前活动的任何事务。 如果事务跨越组件,则指向同一持久性单元的所有实体管理器对象引用在整个事务中将具有相同的持久性上下文。 因此,通过其他实体管理器引用可以看到通过任何实体管理器引用对实体所做的任何更改。

默认情况下,容器管理的实体管理器的持久性范围是transactiontransaction-type始终为JTA 。 即,实体管理器对象始终向活动的事务注册。 总之,容器自动管理实体管理器的生命周期和关联的持久性上下文。 如果在事务范围之外调用实体管理器对象,则容器将引发错误。

在应用程序管理的持久性上下文中,实体管理器工厂创建实体管理器对象。 使用@PersistenceUnit(unitName="<PersistentUnitName>")批注时,容器将注入实体管理器工厂对象。 实体管理器的持久性上下文不会与当前活动的事务一起传播。 如果事务跨越组件,则指向同一持久性单元的所有实体管理器对象引用将具有不同的持久性上下文。

默认情况下,应用程序管理的实体管理器的持久性范围为Extended 。 也就是说,默认情况下,持久性上下文跨越事务边界。 transaction-type可以是JTARESOURCE_LOCAL 。 如果transaction-typeJTA,则实体管理器可以通过调用joinTransaction()方法来加入事务。 如果实体管理器对加入全局事务不感兴趣,则使用transaction-type RESOURCE_LOCAL 。 此类型通常在非JEE环境中使用。 总之,容器不管理实体管理器的生命周期和关联的持久性上下文。 明确关闭实体管理器是应用程序的责任。

配置DB2AccountUnit持久性单元

在本节中,我们为实体管理器连接工厂,实体管理器和事务配置DB2AccountUnit和持久性单元。

打开DB2AccountUnit/src/META-INF文件夹中的persistence.xml文件, DB2AccountUnit/src/META-INF清单2中的代码添加到<persistent-unit>元素:

清单2. persistence.xml的更改
<persistent-unit name=”DB2AccountUnit” transaction-type=”RESOURCE_LOCAL”>
   <description>DB2 Account Management</description>
   <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
   <jta-data-source>DB2Datasource</jta-data-source>
<persistent-unit>

我们将DB2AccountUnit持久性单元配置为使用服务器上部署的DB2Datasource数据库连接池。 下一节将说明部署连接池的过程。 它被配置为执行本地事务。 我们使用实体管理器工厂为DB2AccountUnit创建实体管理器。 因此,实体管理器由应用程序管理,默认情况下其持久性范围为EXTENDED 。 不需要时,应用程序负责关闭实体管理器。 我们将在Web应用程序中说明这一方面。 我们使用这些实体管理器对DB2ACCOUNT表执行插入/更新操作。

部署DB2Datasource数据库连接池

  1. 启动服务器,然后在浏览器窗口(http:// localhost:8080 / console中打开Web管理控制台。
  2. 选择控制台导航=>服务=>数据库池以打开数据库池 portlet。 此Portlet列出了所有已部署的数据库池。 单击“ 使用Geronimo数据库池”链接,如图35所示:
    图35.数据库池Portlet
    该屏幕快照显示了数据库池portlet
  3. 在下一个屏幕上,对于DB2Datasource Name Name ,输入DB2Datasource然后为DB2 Type选择DB2 (图36) 。 单击下一步按钮。
    图36.指定数据库池
    该屏幕快照显示了如何指定数据库池
  4. 如下表所示选择驱动程序JAR文件 (也如图37所示):
    数据库名称 样品
    用户名 DB2ADMIN
    服务器名称 本地主机
    密码 <密码>

    图37.驱动程序JAR文件
    该屏幕快照显示了要选择的Driver JAR文件
  5. 单击“ 部署”按钮以在服务器上部署DB2Datasource数据库池。

配置DerbyAccountUnit持久性单元

打开DerbyAccountUnit/src/META-INF文件夹中的persistence.xml文件,并添加清单3中的代码:

清单3:DerbyAccountUnit persistence.xml的更改
<persistence-unit name="DerbyAccountUnit" transaction-type="JTA">
   <description>Derby Account Management</description>
   <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
   <properties>
      <property name="openjpa.ConnectionURL" value="jdbc:derby:AccountDB" />
      <property name="openjpa.ConnectionDriverName"  
            value="org.apache.derby.jdbc.EmbeddedDriver" />
      <property name="ConnectionUserName" value="app" />
      <property name="openjpa.jdbc.SynchronizeMappings" value="false" />
   </properties>
</persistence-unit>

我们将DerbyAccountUnit持久性单元配置为使用来自persistence.xml的连接属性来创建实体管理器。 OpenJPA定义了许多配置属性。 这些属性大多数是为希望自定义OpenJPA行为的高级用户提供的。 我们在Web应用程序中使用@PersistenceContext批注来注入实体管理器。 因此,它是一个容器管理的实体管理器,其生命周期由容器管理。 持久性上下文的范围是事务。 实体管理器参与全局事务以将金额从DB2ACCOUNT表转移到DERBYACCOUNT表。

在Web应用程序中打包持久性单元

在本节中,您将执行以下任务:

  • 创建AccountManagementWEB Web应用程序,并将JPA项目打包在一起。
  • 开发JSP和Servlet。
  • 探索Web应用程序的各个组件。

创建AccountManagementWEB Web应用程序并打包JPA项目

在本节中,我们将创建AccountManagementWEB Web应用程序。 我们将配置Web应用程序以打包DB2AccountUnitDerbyAccountUnit持久性单元。

  1. 右键单击Project Explorer ,然后导航到New => Other ,如图38所示:
    图38.导航到动态Web项目
    该屏幕截图显示了如何导航到动态Web项目
  2. 在下一个向导中,选择“ 动态Web项目” ,然后单击“ 下一步”按钮。
    图39.打开Dynamic Web Project向导
    该屏幕截图显示了如何打开Dynamic Web Projec向导
  3. New Dynamic Web Project向导上,输入AccountManagementWEB作为Project名称,然后选择其他值,如下表(以及图40)所示。 单击下一步按钮。
    项目名称 帐户管理WEB
    目标运行时间 IBM WASCE v2.1
    构型 IBM WASCE v2.1的默认配置

    图40. Dynamic Web Project向导
    屏幕快照显示了Dynamic Web Project向导
  4. Project Facets向导上,选中Dynamic Web Module,JavaWASCE Deployment框,如图41所示。 单击下一步按钮。 我们不会选择Java Persistence复选框,而是使用之前创建的JPA项目。
    图41. Project Facets向导
    屏幕快照显示Project Facets向导
  5. 在“ Web模块”向导上,输入下表中显示的值(和图42)。 单击下一步按钮。
    上下文根 帐户管理WEB
    建立目录 网页内容
    Java源目录 src
    创建部署描述符 选中复选框

    图42. Web模块向导
    屏幕截图显示了Web模块向导
  6. Geronimo Deployment Plan向导上,输入下表中显示的值(和图43)。 单击完成按钮。 此步骤在Project Explorer中创建一个名为AccountManagementWEB的新Web项目。
    群组编号 网页
    工件ID 帐户JPA
    1.0
    神器类型 汽车

    图43. Geronimo部署计划向导
    屏幕快照显示Geronimo部署计划向导
  7. 右键单击Web项目,然后选择属性
    图44.打开“属性”视图
    该屏幕截图显示了如何打开“属性”视图
  8. 单击左侧的Java Build Path ,然后添加DB2AccountUnitDerbyAccountUnit项目(图45)。 由于我们将在Web应用程序中使用sample.jpa.Db2accountsample.jpa.Derbyaccount持久类,因此JPA项目必须在其内部。
    图45.指定Java构建路径
    该屏幕快照显示了如何指定Java构建路径
  9. 单击左侧的J2EE模块依赖关系 ,然后选择DerbyAccountUnitDB2AccountUnit项目(图46)。 将Web应用程序导出到.WAR文件时,JPA项目将打包为DerbyAccountUnit.jarDB2AccountUnit.jar文件打包在WEB-INF/lib文件夹中。
    图46.指定J2EE模块依赖性
    该屏幕快照显示了如何指定J2EE模块依赖项

开发JSP和Servlet

对于本教程的这一部分,您需要下载我们的示例代码。 我们需要将以下JSP,Servlet和类从AccountManagementWEB.war文件添加到AccountManagementWEB项目。

  • JSP
    • 文件夹:/
      • index.jsp
      • Create_Account.jsp
      • Retrieve_Account.jsp
      • Update_Account.jsp
      • Transfer_Amount.jsp
  • 小程序
    • 包:sample.jpa.servlet
      • CreateAccount.java
      • RetrieveAccount.java
      • UpdateAccount.java
      • TransferAmount.java
  • 班级
    • 包:sample.jpa
      • AccountException.java

探索Web应用程序的各种组件

JSP向用户提供Web界面以进行数据输入。 Servlet从HttpServletRequest检索用户输入,并使用JPA对基础数据库( SAMPLEACCOUNTDB )执行数据库操作。 当需要引发任何应用程序异常时,Servlet将创建一个AccountException对象并将其抛出。 应用程序异常被捕获在catch块中,并作为响应显示给用户。

Index.jsp是允许浏览到其他页面的主页。 Create_Account.jsp显示一个HTML表单以收集帐户详细信息。 输入有效的输入值后,单击Submit按钮将提交到CreateAccount servlet。 CreateAccount Servlet从HttpServletRequest检索输入数据,并将帐户详细信息持久存储到SAMPLE数据库中的DB2ACCOUNT表中。 It uses the entity manager obtained from the DB2AccountUnit persistence unit, and performs database operations in the local transaction scope.

Similarly, you can retrienve and update existing accounts using Retrieve_Account.jsp/RetrieveAccount.java and Update_Account.jsp/UpdateAccount.java respectively.

The Transfer_Amount.jsp collects a debit account number in the DB2ACCOUNT table, credit account number in the DERBYACCOUNT table, amount to be transferred, and submits them to the TransferAmount.java servlet. The servlet performs a JTA transaction on the two databases to transfer the amount. It uses entity managers from DerbyAccountUnit and DB2AccountUnit_JTA persistence units, and enlists them in the global transaction. We'll configure the DB2AccountUnit_JTA in the next section.

Configuring persistence units in the Community Edition deployment plan

In this section, you will perform just one task:

  • Configure JTA persistence unit for SAMPLE database.

As explained in the Configure DB2AccountUnit persistence unit section, the DB2AccountUnit is configured as a RESOURCE_LOCAL persistence unit in its persistence.xml . The entity manager created from this configuration performs only local transactions. It does not use the JTA transaction manager from the application server.

The TransferAmount.java servlet needs to update the SAMPLE database (in DB2) as well as the ACCOUNTDB database (in Derby) in a global transaction. So, it needs entity managers that can enlist themselves in the global transaction manager (JTA transaction manager). The DerbyAccountUnit is already configured as a JTA persistence unit. We need another persistence unit to provide a JTA entity manager for the SAMPLE database.

To accomplish this task, we will configure a third persistence unit DB2AccountUnit_JTA in the geronimo-web.xml file of the Web application. Please see the highlighted portion in Listing 4:

Listing 4. Changes to the geronimo-web.xml file
<web:web-app xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" 
 xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"
 xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" 
 xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" 
 xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" 
 xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" 
 xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" 
 xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1" 
 xmlns:pers="http://java.sun.com/xml/ns/persistence" 
 xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0">

    <dep:environment>
        <dep:moduleId>
            <dep:groupId>web</dep:groupId>
            <dep:artifactId>accountJPA</dep:artifactId>
            <dep:version>1.0</dep:version>
            <dep:type>car</dep:type>
        </dep:moduleId>
      <dependencies>
            <dependency>
                <groupId>console.dbpool</groupId>
                <artifactId>DB2Datasource</artifactId>
            </dependency>
      </dependencies>        
</dep:environment>

    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
      <persistence-unit name="DB2AccountUnit_JTA" transaction-type="JTA">
       <description>DB2 Account Management</description>
          <provider>
            org.apache.openjpa.persistence.PersistenceProviderImpl
          </provider>
       <jta-data-source>DB2Datasource</jta-data-source>
      </persistence-unit>
    </persistence>

   <web:context-root>/AccountManagementWEB</web:context-root>
</web:web-app>

The TransferAmount.java servlet uses DB2AccountUnit_JTA and DerbyAccountUnit persistence units to perform a global transaction.

The servlets in the AccountManagementWEB application use entity managers of DB2AccountUnit and DB2AccountUnit_JTA persistence units. These persistence units connect to the SAMPLE database running in DB2, and use DB2Datasource deployed on the server. Hence, we need to declare a dependency in the geronimo-web.xml on the DB2Datasource . The moduleId of the DB2Datasource connection pool is console.dbpool/DB2Datasource/1.0/car .

Deploying the Web application.

In the section we perform the following tasks:

  • Deploy the AccountManagementWEB application
  • Explore an alternative way to deploy the AccountManagementWEB application.

Deploy the AccountManagementWEB application

  1. Right-click AccountManagementWEB and select Run As => 1 Run on Server .
    Figure 47. Running the application
    Screen shot showing how to run the application
  2. On the Run on Server wizard, select Choose an existing server radio button , IBM WASCE v2.1 Server at localhost , and check on the Always use this server when running this project . as Figure 48 shows. 单击下一步按钮。
    Figure 48. Choosing the server
    Screen shot showing how to choose the server
  3. On the next screen, click the Finish button to deploy the application on to the server.
  4. On the Eclipse main content area, you see the index.jsp in the browser window, as Figure 49 shows:
    Figure 49. index.jsp running in a browser
    Screen shot showing index. jsp running application

Alternative way to deploy the AccountManagementWEB application.

Alternatively, you can use the following procedure to deploy the application outside the Eclipse environment.

  1. Right-click on the Web application and export it as a WAR file, as Figure 50 shows:
    Figure 50. Exporting the application as a WAR
    Screen shot showing how to export the application
  2. On the WAR Export wizard, provide the values shown in the following table (and Figure 51) and click the Finish button.
    Web Module AccountManagementWEB
    Destination destination directory
    Export Source files Check on the checkbox
    Overwrite existing file Check on the checkbox

    Figure 51. WAR Export wizard
    Screen shot showing  WAR         Export wizard
  3. Open a Command window and start the Community Edition server by entering this command: <wasce_home>/bin>startup.[sh|bat] .
  4. Deploy the application using the command in Listing 5:

    Listing 5. Deployment command

    <wasce_home>\bin>deploy.bat --user system --password manager 
    deploy AccountManagementWEB.war
    
    Using GERONIMO_BASE: <wasce_home>
    Using GERONIMO_HOME: <wasce_home>
    Using GERONIMO_TMPDIR: var\tempUsing JRE_HOME: <jdk_home>\jre
    Deployed web/accountJPA/1.0/car 
    @ /AccountManagementWEB
    <jdk_home> is the location where the IBM Java SDK is installed.

Running the Web application

In this section we walk through running the application, and perform the following tasks:

  • Insert sample account details into the DB2ACCOUNT table
  • Retrieve the existing account details and update the values.
  • Transfer an amount from the DB2ACCOUNT table to DERBYACCOUNT

Insert sample account details into the DB2ACCOUNT table

  1. Open a Web browser window and open the url http://localhost:8080/AccountManagementWEB/ . This step displays the main page shown in Figure 52:
    Figure 52. AccountManagement main page
    Screen shot showing AccountManagement main page
  2. Click on the Create a New Account link. This displays an HTML form to enter the account details. Enter some account details as shown in Figure 53, and click the Submit button.
    Figure 53. Create a New Account
    Screen shot showing Create a New Account
  3. You now have a new account with account number 10 in the DB2ACCOUNT table. Listing 6 shows the corresponding code snippet:

    Listing 6. sample.jpa.servlet.CreateAccount.java

    public class CreateAccount 
        extends javax.servlet.http.HttpServlet 
        implements javax.servlet.Servlet 
          {static final long serialVersionUID = 1L;
          
          @PersistenceUnit(unitName="DB2AccountUnit")
           private EntityManagerFactory emf;
    
           EntityManager em;
    
           public void init(ServletConfig config)
             { System.out.println("CreateAccount Servlet created..!"); 
             em = emf.createEntityManager(); 
             }
           
            public void destroy()
              {System.out.println("CreateAccount Servlet destroyed..!");
              em.close();
              emf.close();}
              …
              …
              .…
              protected void doPost(HttpServletRequest request, 
                HttpServletResponse response) 
              throws ServletException, IOException
     
              {try{
                 int accno = Integer.parseInt(request.getParameter("ACCNO"));
                 String ownerName = request.getParameter("OWNERNAME"); 
                 String strDate = request.getParameter("DOP"); 
                 long lgDate=new SimpleDateFormat("MM/dd/yyyy"). 
                     parse(strDate,new ParsePosition(0)).getTime(); 
    
                     java.sql.Date dbDate=new java.sql.Date(lgDate); 
                     String accType = request.getParameter("ACCOUNTTYPE"); 
                     BigDecimal balance = new BigDecimal
                       (request.getParameter("BALANCE")); 
                     em.getTransaction().begin(); 
                     Db2account account1 = em.find(Db2account.class, accno);
    
                      if(account1 != null)
                      { throw new AccountException
                           ("Error : sample.jpa.servlet.CreateAccount : 
                           Account Number already exists:"+accno); 
                      } 
                       
                      Db2account account = new Db2account(); 
                      account.setAccno(accno); 
                      account.setAccountType(accType); 
                      account.setBalance(balance); 
                      account.setDateOpen(dbDate); 
                      account.setOwner(ownerName); 
                      
                       em.persist(account); 
                       em.getTransaction().commit(); 
                       response.sendRedirect("Create_Account.jsp");}
    
              catch (AccountException ae)
                {ae.printStackTrace();
                  PrintWriter out = response.getWriter();
                  printMessage(ae,out);
                  em.getTransaction().rollback();}
    
               catch (Exception e)
                  {e.printStackTrace();
                   PrintWriter out = response.getWriter();
                   printMessage(e,out);em.getTransaction().rollback();
                  }
                  }

    We used the entity manager factory to create an entity manager. Since it is an application-managed entity manager, the servlet closes the entity manager and the entity manager factory using the destroy() method. We also used EntityTransaction to perform the local transactions. The transaction rolls back in the catch block when there is an application exception or system exception.

  4. Create another account like the one in Figure 54:
    Figure 54. Creating a new account
    Screen shot showing how to create a new account
  5. Try to create another account with the account number 10, which is already inserted in the table (Figure 55):
    Figure 55. Create another new account
    Screen shot showing another new account with account number 10

    This data throws an error stating that the account already exists (Figure 56):

    Figure 56. Error message
    Screen shot showing error message

Retrieve the existing account details and update the values.

  1. From the main page, click on the Update an Existing Account link. This will display a HTML form to input account number. Provide the value as 10 and click on the Submit button, as Figure 57 shows:
    Figure 57. Updating an existing account
    Screen shot showing Update an Existing Account form
  2. The Update Account Details form opens, filled with the details of the account number 10. To update the details, modify the values (except for account number) and click the Submit button (Figure 58):
    Figure 58. Updating account details
    Screen shot showing Update Account Details form

Transfer an amount from the DB2ACCOUNT table to DERBYACCOUNT

  1. From the main page, click the Transfer Amount link to display a form to input the debit account number, credit account number and the amount to transfer. Enter some values as in Figure 59, and click the submit button.
    Figure 59. Transferring an amount of money
    Screen shot showing Transfer Amount form

    Listing 7 shows the corresponding code snippet:

    Listing 7. sample.jpa.servlet.TransferAmount

    public class TransferAmount extends javax.servlet.http.HttpServlet 
       implementsjavax.servlet.Servlet 
    {static final long serialVersionUID = 1L;
    
     @PersistenceContext(unitName="DerbyAccountUnit")
     private EntityManager derbyManager;
    
     @PersistenceContext(unitName="DB2AccountUnit_JTA")
     private EntityManager db2Manager;
      …
      …
      ....
      protected void doPost(HttpServletRequest request, 
       HttpServletResponse response) 
       throws ServletException, IOException 
    
       {UserTransaction ut;
        try{
          int debitAccno = Integer.parseInt(request.getParameter("DEBITACCNO"));
          int creditAccno = Integer.parseInt(request.getParameter("CREDITACCNO"));
          BigDecimal bigAmount = new BigDecimal(request.getParameter("AMOUNT"));
    
          double amount = bigAmount.doubleValue();
          Context ctx = new InitialContext();
          ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
    
          ut.begin();
    
          Db2account db2Account = db2Manager.find(Db2account.class, debitAccno);
          Derbyaccount derbyAccount = derbyManager.find(Derbyaccount.class, creditAccno);
    
          db2Manager.refresh(db2Account);
          derbyManager.refresh(derbyAccount);
    
          if(db2Account == null)
          throw new AccountException
             ("Error : sample.jpa.servlet.TransferAmount : 
                Debit  Account Number does not exist:"+debitAccno);
    
          if(derbyAccount == null)
          throw new AccountException
             ("Error : sample.jpa.servlet.TransferAmount :  
                credit Account Number does not exist:"+creditAccno);
    
          if(db2Account.getBalance().doubleValue() < amount)
          throw new AccountException
              ("Error : sample.jpa.servlet.TransferAmount :  
                Insufficient funds to transfer in debitaccount:"
               +"debitAccno("+debitAccno+")"+"Amount("+amount+")"
               +"Available Balance("+db2Account.getBalance()+")");
    
          db2Account.setBalance(new bigDecimal
             (db2Account.getBalance().doubleValue()  - amount));
          derbyAccount.setBalance(new BigDecimal
             (derbyAccount.getBalance().doubleValue()  + amount));
    
         db2Manager.flush();
         derbyManager.flush();
    
          ut.commit();
    
          response.sendRedirect("Transfer_Amount.jsp");
        }
    
       catch (AccountException ae){ae.printStackTrace();
        {PrintWriter out = response.getWriter();
        printMessage(ae,out);
        }
    
       catch (Exception e)
         {e.printStackTrace();
          PrintWriter out = response.getWriter();
          printMessage(e,out);
        }
    }
  2. The TransferAmount servlet injects derbyManager and db2Manager entity managers using the @PersistenceContext annotation. Therefore, the injected objects are container-managed entity managers. The container manages the life cycle of the persistence context. Hence, there is no code to create entity managers and close them later when not needed. The servlet gets the UserTransaction object and begins the transfer amount transaction. The entity managers are automatically enlisted in the global transaction when any methods are invoked within the transaction scope.
  3. If the debit account does not have sufficient funds then application will throw an error, as you can see in Figures 60 and 61.
    Figure 60. Entering an account number with insufficient funds
    Screen shot showing tranfer of $7000.00
    Figure 61. Insufficient funds error message
    Screen shot showing Insufficient funds error message

结论

You have seen how easy it is to develop persistence applications using JPA. The Eclipse IDE makes it even easier to generate the persistent classes from the underlying tables. You can develop the independent persistent units and package them into Java EE applications. Community Edition also lets you declare persistent units in deployment plans.

Most importantly, the POJO-based programming model eliminates boiler-plate code from the application components. The database connection properties, transaction configuration, and mapping information are delegated to annotations or XML files. With Community Edition, you don't need any server specific configurations to run the JPA applications.


翻译自: https://www.ibm.com/developerworks/websphere/tutorials/0807_madgula/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IBM WebSphere Application Server(简称WebSphere)是IBM公司推出的一款基于Java的应用服务器。它是目前市场上最受欢迎的应用服务器之一,广泛应用于企业级应用程序开发和部署。 WebSphere具有强大的功能和提供稳定可靠的性能。它支持多个操作系统平台,如Windows、Linux和AIX等,适用于各类企业级应用。它提供了集群、负载均衡和故障恢复等功能,保证了系统的高可用性和可靠性。 WebSphere使用Java EE(Java Platform, Enterprise Edition)作为开发标准,支持大量的Java EE技术,如Servlet、JSP、EJB和JMS等,这样开发者可以使用这些技术来构建可扩展的、分布式的企业级应用程序。 此外,WebSphere还提供了一系列的工具和组件,方便开发人员进行应用程序开发和部署。比如,它提供了集成的开发环境和调试工具,帮助开发人员提高开发效率和代码质量。它还支持基于开放标准的Web服务,使得应用程序能够与其他系统进行无缝集成。 作为一款商业级应用服务器,WebSphere也提供了强大的安全控制机制,帮助企业保护应用程序和数据的安全。它支持传输层安全协议(TLS)和基于角色的访问控制等安全特性,以及集成的认证和授权机制,确保应用程序的安全性和合规性。 总的来说,IBM WebSphere Application Server是一款功能强大、稳定可靠的企业级应用服务器,为企业提供了全面的开发、部署和管理功能,帮助企业构建可扩展的、分布式的Java应用程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值