在VisualWeb应用程序中使用JavaPersistenceAPI

借助 NetBeans IDE 6.0 和 Visual Web 工具,您可以使用 Visual Web 数据提供程 序组件以及 Java Persistence API(JPA)来编写连接到数据库表的应用程序。建立了到 数据库表的连接之后,可以使用 Java Persistence API 执行数据库 CRUD 操作(即创建 、读取、更新和删除操作)。在开发基于数据库的应用程序时,使用 Java Persistence API 能提供更高的灵活性。

本文是本系列文章的第 1 篇(共两篇),主要介绍在 Visual Web 应用程序中使用 Java Persistence API 所需的设置步骤。您将了解如何使用此 API 连接或绑定到数据库 表,从而能够访问表中的数据。在第 2 篇文章(“使用 Java Persistence API 修 改数据库表行”)中,您将了解如何使用此 API 添加、更新和删除数据库表行。此 外,本文还提供了一些技巧,可以最大限度地利用 NetBeans IDE 及其可视的 web 函数 。

本文将使用以下技术和资源

JavaServer Faces 组件/ Java EE 平台 1.2/Java EE 5* Travel 数据库 不需要

* 要利用 NetBeans IDE 6.0 的 Java EE 5 功能,我们需要使用一个与 Java EE 5 规范完全兼容的应用服务器,比如说 Sun Java Application Server 9/GlassFish。

本文专门适用于 Sun Java Application Server PE 9.0 Update Release 1 和 Tomcat 6.0.14。如果您使用的是其他服务器,请参考 发行说明 和 常见问题解答 了解 已知问题和解决方法。有关支持的服务器和 Java EE 平台的详细信息,请参阅 发行说明 。

概述

本文(本系列的第 1 篇文章)首先介绍了如何将 NetBeans IDE Visual Web Table 组件直接绑定到一个 Object 数组或列表(以及 POJO 或 Plain Old Java Object)。对 使用 Visual Web 工具访问数据库表很熟悉的开发人员一定使用过数据提供者组件。您也 许已将一个 Table 组件从 Palette 移动到一个页面上,然后将此页面上的数据库表移动 到 Table 组件上。当将数据库表移动到页面上时,Visual Web 工具会为您创建一个数据 提供者组件,这个数据提供者处理数据库绑定和数据访问。

现在要将同一个 Visual Web Table 组件绑定到数据库表,而不需要数据提供者支持 ;使用 Java Persistence API 来进行绑定。使用 JPA,可以获得数据库表数据并当作实 体 bean 列表或数组,然后直接将数据绑定到 Visual Web Table 组件,无需使用 ObjectListDataProvider 或 ObjectArrayDataProvider。然后可以使用 Visual Web Table 组件功能操作该数据。

除了讨论 Java Persistence API 的使用之外,我们还要讨论 NetBeans IDE 的一些 特性。我们将介绍如何使用 IDE 实现以下功能:

创建数据库表、列和键

将一个 Visual Web 项目链接到一个标准 Java SE 项目,以使 web 项目能够使用 Java SE 项目中的类。

定义一个持久单元,作为任何 JPA 应用程序的强制配置文件。

通过数据库表生成实体类

使用 Java 源代码编辑函数来生成代码、修复遗失的导入语句,以及重新格式化代码

将属性绑定到数据

后续文章将展示如何使用指定 Visual Web 组件(比如 Grid Panel)控制页面布局。

为何使用 Java Persistence API

Java Persistence API(在 Java EE 5 平台中引入)可用于像 web 应用程序或 EJB 这样的企业应用程序和它们的部署到 Java EE 5 环境(如 GlassFish)或者)或 Java EE 平台外部的远程客户机。如果选择 Java Persistence API,可以使用 JPA 让应用程序绕 过 Visual Web 数据提供者组件直接与底层数据库通信。

使用 Java Persistence API 有许多好处。第一,JPA 是一个简单且轻量型的编程模 型,其中 POJO(plain old Java object)是“一类居民”。

将实体对象作为 POJO 处理可以引起使用 Java Persistence API 的其他好处。由于 实体是 POJO,一个实体类可以扩展另一个实体类或非实体类,一个非实体类也可以可以 扩展实体类。作为 POJO,实体类可以被序列化并通过网络发送到其他地址空间,也可以 用于不支持持久性的环境中。从而无需使用任何特定的数据转换对象将实体发送到远程位 置。

借助 Java Persistence API,可以使用标准应用程序编程接口来执行与实体相关的典 型数据库操作(Create/Read/Update/Delete 或 CRUD 操作)。还改善了应用程序的可移 植性。由于第三方持久提供者更容易为数据库系统开发或提供插件,所以不用考虑应用程 序的可移植性就可以将不同的 Java EE 容器与不同的系统组合起来。

另外,可以使用底层数据库的本机查询语言来执行查询。而且,也简化了使用 Java Persistence API 的实体打包规则。如果应用程序具有较高的事务性需求,那么使用 JPA 也许更好,因为它支持乐观锁定(也就是说,它避免了会影响到性能的锁定),但是与其 他用户的冲突可能会引起一些事务的失败。

关于 Java Persistence API 的更多信息,请参阅文章 “Java Persistence API:一个更简单的实体持久性编程模型”。

关于 Java Persistence API 的深入指导,请参阅文章 在桌面应用程序中使用持久性 API。

创建数据库表

以下的逐步指导假设您已经设置了一个叫做 sample 的数据库,其中包括一个叫做 Users 的数据库表。 Users 表应该有 4 列,如下:

user_id – 主键;类型:整型

userName – 类型:字符串

password – 类型:字符串

email_address – 类型:字符串

执行 SQL 语句

可以使用 Services 窗口中的 Databases 节点将 Users 表添加到 sample Derby 数 据库。可以从一个文件执行 SQL 脚本创建此表或者单独执行每行 SQL 代码。Services 窗口(以前称作 Runtime 窗口)中的数据库表节点上下文菜单函数包括用于创建新表和 执行 SQL 代码的函数。

图 1:SQL 执行命令

Execute Command 功能打开一个 EdiTor 窗口,可以向其中输入一行或多行 SQL 代码 。单击 Run 按钮执行窗口的内容。请确保 Connection 字段指示您已连接到 sample 数 据库。

图 2: 创建 Users 表的 SQL 代码

定义主键值

可以使用以下代码在 Derby sample 数据库中创建 Users 表。注意子句 GENERATED ALWAYS AS IDENTITY 指示 Derby DBMS 将生成 user_id 主键值,并且当添加一个新纪录 时该主键值自动递增。如果向此表中手动添加记录,比如使用 INSERT INTO 代码,请确 保使用保留字 DEFAULT 来指示 user_id 的值是由数据库提供的。

代码示例 1:创建 Users 表的 SQL 代码

create table "APP"."USERS" (  userName VARCHAR(50), password VARCHAR(12), email_address VARCHAR (50),      user_id INTEGER GENERATED always AS IDENTITY);alter table Users add constraint usersPK PRIMARY KEY (user_id);INSERT INTO Users VALUES ('Joe', 'joepw', 'joe@email.com',DEFAULT);INSERT INTO Users VALUES ('Sarah', 'mypassword', 'sarah@sun.com', DEFAULT);INSERT INTO Users VALUES ('Jane Doe', 'janie', 'jane@hotmail.com', DEFAULT);

还有使用 Derby 定义主键值的其他方法。除了 Apache Derby 站点 上的 Derby Reference Manual 之外,还可以参考 Brian Leonard 撰写的关于此项目的 博客文章。

但是请记住,不同的数据库管理系统处理主键值的方式也不同。例如,对于 MySQL, 用于生成和自动递增主键的表定义为:

`user_id` int(10) unsigned NOT NULL auto_increment, …

然后,将从此数据库表定义生成一个实体类。生成的实体类是数据库表的 Java Persistence 表示。因为 TopLink 是 JPA 的参考实现,可以参考 TopLink 文档 获得关 于 id 生成的更多信息。使用 Derby,必须向生成的类手动添加注释,以对主键指示生成 的值策略(@GeneratedValue))。使用 MySQL,无需在此实体类中指定生成的值策略。

将 Visual Web 项目链接到 Java Standard Edition 项目

要使用 Visual Web 应用程序的 Java Persistence API,实际上还需要创建两个项目 。第一个是 Visual Web 项目。另一个是 Java Standard Edition (SE) 应用程序项目, 包括 web 应用程序将要调用其代码的一些类。从该 Java SE 应用程序项目中生成一个持 久单元,以获得 Java Persistence API 的一个句柄。web 应用程序然后使用在 Java SE 应用程序项目中创建的类建立数据库绑定,随后执行数据库更新、删除和添加操作。

创建项目

创建 Java SE 应用程序项目。首先创建 Java SE 应用程序项目,这是一个普通的 Java 项目。单击工具栏上的 New Project 图标(Ctrl+Shift+N),然后在 Categories 列表中选择 Java,在 Project 列表中选择 Java Application。然后单击 Next 按钮。

图 3: 创建 Java 应用程序(单击放大图像)

在 New Java Application 窗口中,将项目名称设置为 TestModelApp。还需要将包设 置为 com.samples.model。可以通过将默认的 Create Main Class 条目由 textmodelapp.Main 更改为 com.samples.model.Main 来实现。单击 Finish 按钮。

图 4: 设置项目和包名称

创建 Visual Web 项目。在 New Project 对话框中选择 Web 类别,并选择 Web Application 项目,然后单击 Next 按钮。

图 5:创建 Web 项目

在 New Web Application 对话框中,将项目名称设置为 TestWebApp。项目位置应该 默认与 TestModelApp 项目位置相同。单击 Next 按钮转到下一屏幕,在其中选择框架

图 6: 设置 Web 项目名称和位置

为框架选择 Visual Web JavaServer Faces。当这样选择时,屏幕显示配置设置。将 Default Java Package 设置由 testwebapp 更改为 com.samples.web。完成这一步之后 ,TestModelApp 和 TestWebApp 会作为节点出现在 Project 窗口中。单击 Finish 按钮 。

图 7: 设置 Web 应用程序框架和包

将项目链接起来

现在需要将两个项目链接起来。具体来说,需要让 TestModelApp 作为 TestWebApp 项目的依赖项。要将 TestModelApp 作为 TestWebApp 的依赖项目,需要将 TestModelApp.jar 文件添加到 TestWebApp 项目。下面是操作方法:

在 Projects 窗口中右键单击 TestWebApp 项目节点,然后从上下文菜单中选择 Properties 选项。

在 Project Properties 对话框中,在左侧的 Categories 部分单击 Libraries 节点 。然后,单击 Add Project 按钮。

图 8: 添加编译时库

在 Add Project 窗口,浏览到 TestModelApp 项目的位置然后选择它。然后,单击 Add Project JAR Files 按钮。此步骤将 TestModelApp jar 文件添加到 TestWebApp 项 目的运行时库中,而且 TestModelApp 会出现在 Project Properties 屏幕中。单击 Project Properties 屏幕中的 OK 按钮,完成此过程。

图 9: 添加 JAR 文件

绑定数据库表

使用 Java Persistence API 在数据库表和 Visual Web JSF 应用程序中使用的表可 视化组件之间传递信息。进行此绑定后,使用 API 获取数据库表的行,但是使用 Visual Web Table 组件的内置显示功能显示数据。

连接到数据库

开始之前,需要将数据库连接到 TestWebApp 项目中的 Users 表。如果使用示例 Derby 数据库而且还没有与之连接,那么打开 Services 窗口,展开 Databases 节点, 打开 jdbc:derby://localhost:1527/sample [app on APP] 节点的上下文菜单并选择 Connect。如果使用不同的 DBMS,那么如果需要,可以为数据库设置一个驱动程序,并根 据必须的连接参数创建一个新连接。(如果将数据库名称作为示例,将会更加容易执行剩 下的步骤)。

如果还未创建 Users 表,那么现在是时候创建了:参阅 创建数据库表。

在 Services 窗口验证到数据库的连接是否建立。打开 Databases > sample database Tables 节点并验证 Users 表是否正确。 创建表示 Users 数据库表的 Java 持久实体类

创建一个表示 Users 表的实体类。正如前面提到的,实体类是数据库表定义的 Java Persistence 表示。JPA 使用 Java 语言注释功能将 POJO 标记为带有对象关系映射信息 的 JPA 实体。使用 Entity Classes from Database 函数在 TestModelApp 中创建实体 类。

在 Projects(或 Files)窗口中右键单击 TestModelApp 项目。从上下文菜单中选择 New > Entity Classes from Database 选项。

此时将显示 New Entity Classes from Database Database Tables 对话框。如果 Database Connection 字段是空的,则从下拉列表中选择示例数据库。Available Tables 列显示示例数据库中的所有表,包括 Users 表。选择 USERS 表并单击 按钮Add 将 Users 移动到 Selected Tables 列。移动 Users 表后单击 Next 按钮。

图 10: 为实体类选择数据库表

此时将出现 Entity Classes 对话框。IDE 显示数据库表名称 Users,并建议一个类 名 Users。(如果需要,双击类名进行更改)。对话框还指示包为 com.samples.model。 单击 Create Persistence Unit 按钮。

图 11: 创建持久单元

创建持久单元

在 Create Persistence Unit 对话框中,将 Persistence Unit Name 设置为 samplePU。保留其他字段的默认值。单击 Create 按钮,然后在 Entity Classes 屏幕中 单击 Finish 按钮完成操作并创建 samplePU 持久单元。

图 12: 为持久单元命名

验证持久单元是否正确创建,这是一个不错的想法。为此,展开 TestModelApp Source Packages > META-INF 节点并双击 persistence.xml 文件。Design 窗口将显 示关于持久单元的信息,而 NavigaTor 窗口将显示 XML 属性。

图 13: 验证持久单元

单击 XML 标签查看完整的 XML 清单。文件中的属性应该正确反射到数据库名称、url 、驱动程序、密码,以及包和类名(com.samples.model.Users)。事务类型为 RESOURCE_LOCAL,提供者为 oracle.toplink.essentials.PersistenceProvider。重点注 意:确保正确填写了密码字段。

图 14: 持久单元 XML 定义

使用 JPA 设置键属性

如果使用的是 Derby 数据库,需要对生成的 Users.java 代码进行一些修改,以处理 主键值的自动生成。但是,其他数据库系统可以以不同的方式处理主键值生成,对生成的 Users.java 类所做的任何修改都必须与底层数据库的主键生成策略匹配。

@Id 和 @GeneratedValue 注释

创建 Users 实体类之后,需要修改该类,以便让数据库自动生成主键字段(用户 id 字段)。JPA 使用 @Id 注释标识主键。向主键添加第二个注释,指示生成主键值的策略 :@GeneratedValue(strategy=GenerationType.),其中策略子句是可选的。 注意,选择的生成策略必须与数据库的性能相关联。

使用 Derby 数据库生成主键值

因为 Derby 数据库支持 IDENTITY 列类型,因此可以为主键生成一个惟一值,这个任 务可以由数据库来完成。因此,向主键定义中添加以下代码行:@GeneratedValue (strategy = GenerationType.IDENTITY).

进行修改之后,定义表的 Users.java 代码应该如下所示:

代码示例 1:经过修改的 Users.java 类

public class Users implements Serializable { @Column(name = "USERNAME") private String username; @Column(name = "PASSWORD") private String password; @Column(name = "EMAIL_ADDRESS") private String emailAddress; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "USER_ID", nullable = false) private Integer userId; ...使用 Fix Imports 功能

注意 @GeneratedValue 标记需要两个类:javax.persistence.GeneratedValue 和 javax.persistence.GenerationType。使用 Fix Imports 函数导入这些类。右键单击源 代码编辑窗口的任何地方,并从弹出菜单选择 Fix Imports。Fix Imports 函数将这两个 导入语句添加到类:

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

正如上面提到的,其他数据库可能需要对 Users.java 代码进行不同的修改,或者根 本不作修改。例如,对于 MySQL 数据库,不需要包含 @GeneratedValue 注释,因为如果 在创建表定义时为 user_id 列指定了 auto_increment,数据库会自动生成主键值。

创建类

创建实体控制器类

继续在 TestModelApp 项目中操作,在 com.samples.model 包中创建一个叫做 UserController 的新类。(我们将在下面提供此类的代码,可以将它粘贴到您的类中) 。

展开 TestModelApp > Source Packages > com.samples.model 节点。注意包 中已经有两个类:Main.java 和 Users.java。右键单击 com.samples.model 节点并选择 New > Java Class 选项。在 New Java Class 对话框中,将类名称设置为 UserController(将其位置保留为 Source Packages 并将包名称保留为 com.samples.model)。

图 15: 创建 UserController 类

在 Edit 窗口中应该可以看见源代码框架。向类添加如下代码:

代码示例 2:UserController 代码

private EntityManagerFacTory emf;private EntityManager getEntityManager() {if(emf == null){  emf = Persistence.createEntityManagerFacTory("samplePU");}  return emf.createEntityManager();}public Users[] getUsers() {  EntityManager em = getEntityManager();  try{    javax.persistence.Query q = em.createQuery("select c from Users as c");    return (Users[]) q.getResultList().toArray(new Users[0]);  } finally {    em.close();  }}

使用 Fix Imports 函数导入需要的类。(在源代码编辑窗口中右键单击,从弹出菜单 选择 Fix Imports 选项)。这样可以将以下 3 个导入语句添加到类中:

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFacTory;

import javax.persistence.Persistence;

可以使用 Format 函数(在同一个弹出菜单中)设置代码对齐的格式。

注意 UserController 类包含方法 getUsers,该方法调用 javax.persistence.EntityManager 接口上的 createQuery 方法创建一个查询,该查询 从 Users 表返回数据的行。查询的结果作为一个数组返回。

将实体 bean 绑定到表组件

您已经将用于访问 Users 数据库表的实体组件绑定到 TestWebApp 项目中的一个 Table 组件。(实体 bean 是在 TestWebApp 中创建的)。在 TestWebApp 项目中进行此 绑定。

下面是绑定步骤:

在 SessionBean1 中创建一个返回 Users 对象数组的属性。

创建一个方法初始化数组。

然后,将 Users 对象数组绑定到 Table 组件。

使用 Java Persistence API Entity Manager 调用 Users 数组初始化方法。

接下来更仔细地讨论一下这些步骤:

在 Session Bean 中创建一个属性

在 NetBeans IDE 中,可以在一些位置找到托管 bean:在 NavigaTor 窗口,在 Projects 窗口的源代码包节点中,以及在 Files 窗口的 src > java > project -name 节点中。

在 SessionBean1 中创建一个返回 Users 对象数组的属性。在 NavigaTor 窗口中, 双击 SessionBean1 在 Java Source EdiTor 中打开。或者,从 Projects 窗口 TestWebApp > Source Packages > com.samples.web 节点中双击 SessionBean1。 如果没有看到 NavigaTor 窗口,那么尝试在 Design 窗口显示 TestWebApp 的一个页面 ,比如 Page1。NavigaTor 窗口应该显示在 Projects 窗口的下面。如果还是看不到 NavigaTor 窗口,在 Design 窗口单击 Design 标签。

向 SessionBean1 添加一个 users 属性。键入以下代码:private Users[] users;

修复导入。刚输入的代码很可能被标记为错误。如果是这样,使用源代码编辑器的上 下文菜单 Fix Imports 函数来修复此错误。(确保在继续之前改正这个错误)。要修复 此错误,添加以下导入语句: import com.samples.model.Users;

为 users 属性生成 get 和 set 方法。右键单击键入的代码行并选择 Insert Code 动作。从弹出菜单选择 Getter 和 Setter。然后,选择 users:Users[]。

图 16: 向 SsessionBean1 添加用户属性

使用 Insert Code 动作添加公共的 get 和 set 方法。完成之后,SessionBean1 应 该包含以下代码:

代码示例 3:用户属性的 get 和 set 方法

private Users[] users;  public Users[] getUsers() {  return users;}  public void setUsers(Users[] users) {  this.users = users;}创建初始化方法

向 SessionBean1 添加一个 updateUsers 属性。此方法将用来初始化 users 属性。 以下是此方法的代码:

代码示例 4:updateUsers 方法

public void updateUsers(){   UserController usersController = new UserController();   users = usersController.getUsers();}

使用 Fix Imports 函数修复 updateUsers 需要的导入。如果代码中包含错误,执行 Save All files 清除这些错误。

将 updateUsers 方法的调用添加到 SessionBean1 init 方法中:updateUsers ();.SessionBean1 init 方法应该如下所示(未显示注释行):

代码示例 5:SessionBean1 init 方法

public void init(){   super.init();   try {     _init();   } catch (Exception e) {     log("SessionBean1 Initialization Failure", e);     throw e instanceof FacesException ? (FacesException) e: new FacesException(e);   }   updateUsers();}

保存所有文件。

构建 TestModelApp 和 TestWebApp 项目。

将属性绑定到表组件

现在已经将刚添加的 users 绑定到一个 Table 组件了。

在 TestWebApp > Web Pages 中,双击 Page1.jsp 在 Design 窗口中打开此页面 。

将 Table 组件从 Palette 拖到 Design 窗口中的页面上。应该如下图所示:

图 17: 向 Page1 添加 Table 组件

右键单击页面上的 Table 组件并在上下文菜单中单击 Bind to Data。在 Get Data From 下拉列表中选择 users(从 SessionBean1)作为绑定数组。(注意如果在下拉列表 中没有 users 属性,右键单击 Design 窗口并单击上下文菜单中的 Refresh 选项。或者 在工具栏上单击 Refresh 按钮。如果还是未在下拉列表中看到 users 属性,那么选择并 重新打开 TestWebApp 项目)。单击 OK 按钮。

图 18:在 Bind to Data 对话框中选择用户

Design 中显示的 Table 组件的更改如下。如果需要,调整显示的列。

图 19: Design 窗口中绑定到用户数组的 Table 组件

部署和运行 TestWebApp 项目。显示 Table 组件,并且如果为数据库表创建了示例数 据库,那么数据应该显示为如下形式:

图 20: 浏览器中 Page1 上的 Table 组件

结束语

本文讨论了使用 Visual Web 应用程序的 Java Persistence API 的必要步骤。展示 了如何设置 Java SE 项目和 Visual Web JSF 项目并将它们链接起来。也展示了如何创 建数据库表和需要的键,以及使用 Java Persistence API 绑定到数据库。本文提供了访 问数据库表所需的定制 Java 代码,此代码演示了如何创建实体 bean 保存表数据。最后 ,还展示了如何将实体 bean 绑定到 Visual Web Table 组件,以及 Table 如何简化数 据库表数据的显示。

真凉爽啊!青山绿水映入我的眼中,景色怡人啊!

在VisualWeb应用程序中使用JavaPersistenceAPI

相关文章:

你感兴趣的文章:

标签云: