执行插入、更新和删除操作
由 NetBeans 教程组创建
|
本教程介绍了如何使用具备 Web 功能的 NetBeans IDE 构建一个可以创建、检索、更新和删除数据库行的 Web 应用程序。该应用程序提供一个主数据的下拉列表以及一个同步的详细信息表。该应用程序的用户可以在详细信息表及其关联数据库中添加、更新和删除记录。
本教程使用了其他基础教程中介绍的一些概念。如果您不具备 IDE 及其设计组件的基本知识,可以考虑首先阅读一些入门教程,比如 Visual Web JSF 应用程序开发入门 和 使用 Databound 组件访问数据库。
|
预计时间:45 分钟
目录
|
|
 |
本教程将使用以下技术和资源
JavaServer Faces 组件/
Java EE 平台 |
1.2/Java EE 5*
1.1/J2EE 1.4 |
| Travel 数据库 |
必需 |
* 为了利用 NetBeans IDE 的 Java EE 5 功能,可以使用完全与 Java EE 5 规范兼容的应用程序服务器,比如 Sun Java Application Server 9/GlassFish。
本教程专门适用于 GlassFish v2 应用程序服务器。如果您使用的是其他服务器,请参考 发行说明 和 常见问题解答 了解已知问题和解决方法。有关支持的服务器和 Java EE 平台的详细信息,请参阅 发行说明。
创建项目
在本教程中,我们将创建一个单页的 Web 应用程序。您可以先从设计页面布局入手,该页面包含一个人名及其相应的行程,如下图所示。
图 1:初始页面布局 |
设计页面
- 创建一个名为
InsertUpdateDelete 的新 Web 应用程序,该程序使用 Visual Web JavaServer Faces 框架。该应用程序的 Page1.jsp 文件会在 Visual Designer 中打开。
- 从 Palette 的 Basic 区域拖动一个 Drop Down List 组件到页面的左上角。在 Properties 窗口中,将其
id 属性更改为 personDD。
-
从 Basic Palette 中拖动一个 Message Group 组件到页面中,并将其放置在下拉列表的右侧。
该 Message Group 组件可用来显示验证错误和转换错误,并且可以显示由 info 和 error 方法写入到 Java Server Faces 上下文的消息。如果需要调试项目,这些消息将会非常有用。
- 将一个 Table 组件放置在这两个组件的下方。
配置下拉列表
-
打开 Services 窗口,展开 Databases 节点,连接到 Travel 数据库。
如果 TRAVEL 数据库的 jdbc 节点标记显示为连接中断
,并且无法展开该节点,则表明 IDE 未连接到该数据库。要连接 TRAVEL 数据库,请右键单击 TRAVEL 数据库的 jdbc 节点,然后从弹出菜单中选择 Connect 选项。如果出现 Connect 对话框,请输入 travel 作为口令,选中 Remember Password,然后单击 OK 按钮。如果看不到 TRAVEL 数据库的 jdbc 节点,请参见 NetBeans 数据库连接常见问题解答 了解如何为 IDE 提供可用的数据库。 注意: 如果您使用的是 Apache Tomcat,请将 derbyClient.jar 文件复制到 <tomcat_install>/common/lib 目录,然后再尝试连接数据库。
-
展开 TRAVEL 数据库的 jdbc 节点,然后展开 Tables 节点。
注意: 在本教程的其余部分中,我们将 TRAVEL 数据库的 jdbc 节点称为 Travel 节点。
-
将 PERSON 节点拖动到 Visual Designer 中的下拉列表上。
Navigator 窗口的 Page1 部分中将显示 personDataProvider 节点,SessionBean1 部分中将显示 personRowSet 节点。
-
右键单击 Drop Down List 组件,并从弹出菜单中选择 Auto-Submit on Change 选项。
此设置使得每当您从列表中选择新值时,就会将该页面发送到服务器。
-
右键单击该下拉列表,并从弹出菜单中选择 Configure Virtual Forms 选项。
在出现的对话框中,请注意 personDD 显示在窗口的左上角,这表明下拉列表已被选定。
-
单击 New 按钮并在 Name 列中键入 person。双击 Participate 列下面的字段,将其设置为 Yes,然后对 Submit 列执行同样的操作,如下图所示。
图 2:Configuring Virtual Forms |
通过使用虚拟表单,应用程序可避免对 Table 中的数据进行不必要的验证。
- 单击 OK 按钮。
-
单击 Visual Designer 工具栏中的 Show Virtual Forms 按钮
,如图 3 所示。
通过查看虚拟表单,您可以查看 Visual Designer 中的组件与您已经配置的任何虚拟表单之间的关系。
图 3:Showing Virtual Forms |
配置表
-
将 Services 窗口中的 Travel > Tables > TRIP 节点拖动到 Visual Designer 中的 Table 组件上。
如果提示选择接收该节点的目标组件,则选择 table1 并单击 OK 按钮。
-
右键单击 Table 并从弹出菜单中选择 Table Layout 选项。
Table Layout 对话框会显示您刚创建的 tripDataProvider 中可用的字段,并允许您控制要在表中显示哪些字段。
-
使用 < 按钮从右侧的 Selected 列表中删除 TRIP.TRIPID、TRIP.PERSONID 和 TRIP.LASTUPDATED,如下图所示。
|

图 4:将表绑定到数据提供程序 |
- 单击 Options 选项卡,将 Title 更改为
Trips Summary,然后单击 OK 按钮。
-
现在,可视设计器中的 Table 组件应如下图所示。注意:如果未按下图顺序显示各列,可通过重新打开 Table Layout 对话框,单击 Columns 选项卡,并使用 Up 和 Down 按钮来重新排列它们。
图 5:Page1 表布局 |
-
在 Navigator 窗口中,右键单击 SessionBean1 下面的 tripRowSet,并从弹出菜单中选择 Edit SQL Statement 选项。
这将打开 SQL Query Editor。
图 7:添加查询条件 |
-
在窗口中心附近的网格区域,右键单击 PERSONID 行并选择 Add Query Criteria 选项,如下图所示。
-
在 Add Query Criteria 对话框中,将 Comparison 下拉菜单设置为 =Equals 并选择 Parameter 单选按钮,然后单击 OK 按钮。
图 7:Add Query Criteria 对话框 |
字符“=?”将出现在 PERSONID 的 Criteria 字段中,并且条件“WHERE TRAVEL.TRIP.PERSONID=?”会出现在编辑器底部的 SQL 窗格中的 SQL 语句的结尾。
- 关闭 tripRowSet 的 SQL 编辑器。
更改 Column 组件
现在,将列内容更改为可编辑的字段,以准备实现将新行程插入到数据库中的功能。执行此操作时,可通过在 Table 组件中嵌套其他组件以利用其复合特性。
-
右键单击 Table 组件并选择 Table Layout 选项。
将打开 Table Layout 对话框。
-
在 Columns 选项卡中,从右侧的 Selected 列表中选择 TRIP.DEPDATE。在对话框底部的 Column Details 区域,将 Component Type 从 Static Text 更改为 Text Field,如下图所示,然后单击 Apply 按钮。
图 8:更改列的外观 |
- 对 TRIP.DEPCITY 和 TRIP.DESTCITY 执行同样的操作。
- 在 Selected 列表中选择 TRIP.TRIPTYPEID,并将 Component Type 从 Static Text 更改为 Drop Down List。
- 单击 OK 按钮。
-
将 Travel > Tables > TRIPTYPE 节点拖放到 Table 组件中的 Drop Down List 上。如果 Choose Target 对话框打开,选择 dropDown1 选项并单击 OK 按钮。
此操作将创建 triptypeDataProvider。
为表配置虚拟表单
接下来,为表中的输入组件创建一个虚拟表单。通过使用虚拟表单,可以确保在更改 personDD 下拉列表后提交此页时,不会对输入组件进行验证和转换。用户无论何时从下拉列表中选择新人员,都会在表中显示正确的信息。
- 在 Visual Designer 中,按住 Ctrl 键的同时在表中单击,以选择包含文本字段的三个列中的三个 Text Field 组件以及 TRIPTYPEID 列中的 Drop Down List 组件。
- 右键单击其中一个选定的组件,并从弹出菜单中选择 Configure Virtual Forms。
- 在 Configure Virtual Forms 对话框中,请确保窗口的左上角列出了三个 Text Field 和 Drop Down List。如果未按下图所示的方式列出这些内容,请关闭对话框,重新选择它们,然后再试一次。如果已正确列出这些内容,则单击 New 按钮。
-
将新虚拟表单的名称更改为 save,将 Participate 设置更改为 Yes,如下图所示,然后单击 OK 按钮。
图 9:为表元素配置虚拟表单 |
添加事件和初始化代码
现在,将 personDD personDD Drop Down List 和 Table 组件关联起来,以实现以下行为:当用户从列表中选择某人时,表中则会显示出此人的行程。
- 双击 personDD Drop Down List 以创建一个值更改事件方法,并在该方法上打开 Java Editor。
-
在 personDD_processValueChange 方法中,添加 Code Sample 1 中的粗体文本,然后按下 Alt-Shift-F 组合键以重新设置代码格式。
| 代码示例 1:下拉列表事件处理程序 |
public void personDD_processValueChange(ValueChangeEvent event) { Object selectedPersonId = personDD.getSelected(); try { personDataProvider.setCursorRow( personDataProvider.findFirst("PERSON.PERSONID", selectedPersonId)); getSessionBean1().getTripRowSet().setObject(1, selectedPersonId); tripDataProvider.refresh(); form1.discardSubmittedValues("save"); } catch (Exception e) { error("Cannot switch to person " + selectedPersonId); log("Cannot switch to person " + selectedPersonId, e); } }
|
位于 try 子句结尾处的 form1.discardSubmittedValues("save") 语句可确保每当用户从下拉列表中选择新的人员时,将使用与所选人员相关的新信息替换表中所显示的当前行程信息。注意表格中显示旅程信息的所有用户界面元素都参与名为 save 的虚拟表单。
另外,该事件处理器不会抛出异常。而是把它们记录到 server.log 文件。该事件处理器也会调用 error 方法,当出现错误时,该方法会在 Message Group 组件中显示一条错误消息。
-
在 Java 源代码中滚动至 prerender 方法,或者(如果您愿意)使用 Ctrl-F 查找 prerender。将下面以 粗体 显示的代码添加到该方法中。
| 代码示例 2:Prerender 方法 |
public void prerender() { if ( personDD.getSelected() == null ) { Object firstPersonId = null; try { personDataProvider.cursorFirst(); firstPersonId = personDataProvider.getValue("PERSON.PERSONID"); personDD.setSelected(firstPersonId); getSessionBean1().getTripRowSet().setObject( 1, firstPersonId); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + firstPersonId); log("Cannot switch to person " + firstPersonId, e); } } }
|
- 在 Java Editor 中单击右键,然后选择 Format 以使代码正确对齐。
测试应用程序:第 1 部分
单击主工具栏上的 Run Main Project 按钮
以生成、部署和运行项目。当 Web 浏览器呈现此页面时,您会看到一些名字填充了下拉列表,并且表也由一些数据进行了填充。当您从列表中选择某个名字时,与该名字相关的旅程就会显示在表格中。
图 10:部署的应用程序,测试 1 |
添加插入功能
在此部分,我们将通过在数据库中插入行集,实现将行程添加到表中的功能。首先,为 Table 的 Text Field 提供 Message 组件。这些组件可确保当用户输入错误信息时可以看见错误。然后,在页面中添加一个按钮,以便用户可以通过它将新行添加到数据缓冲区中。
- 单击 Design 按钮以便在 Visual Designer 中查看 Page1。
- 在 Palette 的 Basic 区域中,将 Message 组件分别拖放到 Table 的前三列每列的最顶层 Text Field 中。
- 选择第一个 Message 组件。在 Properties 窗口中,滚动至
for 属性,并从下拉列表中选择 textField1 选项。只有当 Message 与 Text Field 正确关联时,Message 文本才会显示关联信息,如图 11 所示。
- 将第二个 Message 组件的
for 属性设置为 textField2。
-
将第三个 Message 组件的 for 属性设置为 textField3。
确保您的应用程序如下图所示。
图 11:关联 Message 组件和 Text Field 组件 |
- 在 Palette 的 Basic 区域,将一个 Button 组件拖到 Page1 中并将其放在靠近第二列顶端的 Table 组件的上面,如图 12 所示。
- 特别注意:在 IE7 中有一个影响 JSF 1.2 Button 组件宽度的已知问题。解决方法是将 Button 组件放在布局组件(Grid Panel、Group Panel 或 Layout Panel)的上面。重设布局组件的大小会自动重设 Button 组件的大小。
- 将文本从
Button 更改为 Add Trip。
- 在 Properties 窗口中,将按钮的
id 属性更改为 add。
- 在 Visual Designer 中,双击按钮以打开 Java Editor,插入点将位于该按钮的
add_action 事件处理程序方法中。
-
将下面以粗体显示的代码添加到该按钮的事件处理程序方法中:
| 代码示例 3:添加行程操作的代码 |
public String add_action() { try { RowKey rk = tripDataProvider.appendRow(); tripDataProvider.setCursorRow(rk); tripDataProvider.setValue("TRIP.TRIPID", new Integer(0)); tripDataProvider.setValue("TRIP.PERSONID", personDD.getSelected()); tripDataProvider.setValue("TRIP.TRIPTYPEID", new Integer(1)); } catch (Exception ex) { log("Error Description", ex); error(ex.getMessage()); } return null; }
|
-
在 Java 编辑器中单击鼠标右键,然后选择 Fix Imports 选项以解决“未找到 RowKey”的错误。
IDE 会将下包添加到导入语句的 Page1.java 段:
import com.sun.data.provider.RowKey;
测试应用程序:第 2 部分
通过单击 Run Main Project 按钮
以生成、部署和运行项目。当 Web 浏览器呈现此页面时,将显示 Add Trip 按钮,如下图所示。每次单击该按钮时,都会在表的底部附加一个新的空行。可以编辑行中的信息,但由于尚未提供行集的保存机制,因此,从下拉列表中选择其他名字时,所做的更改将会丢失。
图 12:部署的应用程序,测试 2 |
修改页面以保存行集
在此部分,将添加第二个行集到项目中。该行集用于计算已使用的最大行程 ID。
- 单击编辑器窗口中的 Design 以返回 Visual Designer 中的 Page1。
-
打开 Services 窗口,选择 Databases > Travel > Tables > TRIP 表,将其拖动到 Navigator 窗口中的 SessionBean1 节点上。
图 13:将 TRIP 表拖动到 SessionBean1 上 |
该操作将为 SessionBean1 创建两个新子节点:tripDataProvider 和 tripRowSet1。
-
在 Add New Data Provider 对话框中,选择 Create SessionBean1/tripRowSet1 单选按钮,将数据提供程序名称更改为 maxTripRowSet,然后单击 OK 按钮。
注意: 行集在对话框中出现了两次。这是一个已知问题,请予以忽略。这不会影响本教程中的应用程序。
图 14:将新的数据提供器添加到 SessionBean1 中 |
此操作将在 SessionBean1 中创建 maxTripDataProvider 和 maxTripRowSet。
- 在 Navigator 窗口中,双击 SessionBean1 > maxTripRowSet 以打开 Query Editor。在 Source Code 窗格(从顶部开始第三个)中单击鼠标左键。删除此处现有的 SQL 查询,然后输入以下查询:
SELECT MAX(TRAVEL.TRIP.TRIPID)+1 AS MAXTRIPID FROM TRAVEL.TRIP
您将会使用 Save 按钮(下一步您将会添加)的操作处理器中的 MAXTRIPID 值。
-
关闭 Query Editor。
注意: Query Editor 的图形化编辑器不支持此查询。如果您看见一个警告对话框提示语法错误,您可以单击 Continue 按钮忽略它。
将用户更改保存到数据库
- 在靠近第一列顶部的 Table 组件上放置一个 Button 组件。为了准确定位,可以参考 图 15 中的 Save Changes 按钮。
- 将按钮文本从
Button 更改为 Save Changes。
- 在 Properties 窗口中,将
id 属性更改为 save。
- 右键单击 Save Changes 按钮,并从弹出菜单中选择 Configure Virtual Forms 选项。
- 在 Configure Virtual Forms 对话框中,请确保
save 显示在左上角的列表中,这样您在此窗口中的更改可以应用到 Save Changes 按钮中。然后,选择 save 虚拟表单,将 Submit 值更改为 Yes,并单击 OK 按钮。
- 在 Visual Designer 中,双击 Save Changes 按钮以打开 Java Editor。在 Java Editor 中,插入点将位于该按钮的
save_action 事件处理程序方法中。
-
将下面以粗体显示的代码添加到该按钮的事件处理程序方法中:
| 代码示例 4:保存操作代码 |
public String save_action() { try { // Get the next key, using result of query on MaxTrip data provider CachedRowSetDataProvider maxTrip = getSessionBean1().getMaxTripDataProvider(); maxTrip.refresh(); maxTrip.cursorFirst(); int newTripId = ((Integer) maxTrip.getValue("MAXTRIPID")); // Navigate through rows with data provider if (tripDataProvider.getRowCount() > 0) { tripDataProvider.cursorFirst(); do { if (tripDataProvider.getValue("TRIP.TRIPID").equals (new Integer(0))) { tripDataProvider.setValue("TRIP.TRIPID", new Integer(newTripId)); newTripId++; } } while (tripDataProvider.cursorNext()); } tripDataProvider.commitChanges(); } catch (Exception ex) { log("Error Description", ex); error("Error :"+ex.getMessage()); } return null; }
|
测试应用程序:第 3 部分
通过单击 Run Main Project 按钮以生成、部署和运行项目。应用程序将可以实现以下功能:
- 可以添加行程并进行保存。然后,该行程将显示在表中并持续存在。如果选择其他人员,然后返回到此人员,则会看到所添加的行程。
- 可以编辑现有的行程信息,并保存所做的更改。
- 如果在 Date 字段中输入除日期之外的内容,应用程序将提供一条错误消息。
- 在保存之前您可以多次单击 Add Trip 按钮,这是一次添加多行的简便方法。如果在保存更改时任何行仍然为空,则会将其保存为空行。
- 如果在单击 Save Changes 之前您切换到其他人员,则会丢失所有更新。
- 如果修改了某些值,然后单击某个列标题以按该列进行排序,则 Table 组件会记住这些暂挂的更改,随后可以保存这些更改。
添加删除功能
在此部分,我们将在表中添加删除功能。利用此功能,用户能够通过从数据库中删除某行来删除行程。在本教程中,Delete 按钮的操作是即时的,并且从数据库中删除行时并不需要使用 Save Changes 按钮。实际上,由于 Delete 按钮的事件处理器使用 commitChanges 方法,它也会像 Save Changes 按钮一样保存所有待定的更改。
向每行添加一个 Delete 按钮
-
单击编辑器窗口中的 Design 以返回 Visual Designer 中的 Page1,然后右键单击 Trips Summary 表,并从弹出菜单中选择 Table Layout 选项。
这将打开 Table Layout 对话框。
- 如有必要,单击 Columns 选项卡,然后单击 New 按钮,将一个新列添加到表中。
-
在 Selected 列表中选择新列的名称后,在 Column Details 区域中进行以下更改:
- Header 和 Footer Text:删除 Header 和 Footer 文本字段中的任何默认文本,使其保持空白。
- Component type:
Button
- Value Expression:
Delete
- Width: 删除任何缺省值,使其保持空白。
- Horizontal Align:
Center
- Vertical Align:
Middle
- 单击 OK 按钮。
- 选择表中最上面的 Delete 按钮,然后在 Properties 窗口中,将
id 属性设置为 delete。
添加事件代码
- 双击 Delete 列中的第一个按钮,以在
delete_action 事件处理器方法中打开 Java Editor。
-
将下面以粗体显示的代码添加到该按钮的事件处理程序方法中:
| 代码示例 5:删除操作代码 |
public String delete_action() { form1.discardSubmittedValues("save"); try { RowKey rk = tableRowGroup1.getRowKey(); if (rk != null) { tripDataProvider.removeRow(rk); tripDataProvider.commitChanges(); tripDataProvider.refresh();} } catch (Exception ex) { log("ErrorDescription", ex); error(ex.getMessage()); } return null; }
|
测试应用程序:第 4 部分
通过单击 Run Main Project 按钮以生成、部署和运行项目。下图显示了该运行应用程序。
部署后,您应该可以从表中删除行,进而将其从数据库中删除。删除操作还会将所有待定更改提交到数据库。
图 15:测试应用程序,第 4 部分 |
添加恢复功能
现在,将恢复功能添加到页面中。使用此功能,用户将可以放弃其编辑并恢复为以前保存的数据。注意:恢复功能不能恢复已保存或删除的行;Save Changes 和 Delete 按钮会将更改提交到数据库。
添加 Revert Changes 按钮
- 单击编辑器窗口中的 Design 以返回到 Visual Designer 中的 Page1,然后从 Palette 中拖一个 Button 组件到 Page1。将该新 Button 放在 Add Trip 按钮的右侧。
- 将按钮文本更改为
Revert Changes。
- 在 Properties 窗口中,将该 Button 组件的
id 属性更改为 revert。
- 双击 Revert Changes 按钮以在
revert_action 方法中打开 Java Editor。
-
将下面代码样例中以粗体显示的代码添加到 revert_action 方法中。
| 代码示例 6:恢复操作代码 |
public String revert_action() { form1.discardSubmittedValues("save"); try { tripDataProvider.refresh(); } catch (Exception ex) { log("Error Description", ex); error(ex.getMessage()); } return null; }
|
配置虚拟表单
如果应用程序使用目前的配置,则会出现一些不理想的行为。例如,如果用户在现有行的第一列中输入无效日期,然后单击 Add 按钮,操作将会失败,由于日期转换错误而拒绝提交表单。用户单击 Add 按钮时的理想行为是:放弃处理表中的输入字段,以便在忽略现有行的暂挂编辑内容的情况下添加新行。
同样地,当用户单击 Revert 按钮时(其目的是放弃所有编辑内容),也应该忽略以上情况的编辑内容。但是,当用户单击 Delete 按钮时,您仍然希望进行验证,因为此按钮不仅删除某个行,而且还会提交所有暂挂的更改,这要求先处理输入字段。
要为确保用户在单击 Add 或 Revert 按钮时放弃处理(包括验证检查)页面上的输入字段,您可以让这些按钮提交虚拟表单。在这种情况下,您可以使两个按钮提交同一个虚拟表单,因为它们需要一个没有参与者的虚拟表单。
-
在 Visual Designer 中,按 Ctrl 键的同时单击以选择 Add、Revert 和 Delete 按钮,单击鼠标右键,然后从弹出菜单中选择 Configure Virtual Forms 选项。
在 Configure Virtual Forms 窗口中,add、revert 和 delete 应出现在左上角,表明这些按钮处于选定状态。
-
在 Configure Virtual Forms 窗口中,单击 New 按钮,将该新虚拟表单命名为 add/revert/delete,然后将 Submit 设置为 Yes。单击 OK 按钮。
图 16:为 Add、Revert 和 Delete 按钮配置虚拟表单 |
测试应用程序:第 5 部分
通过单击 Run Main Project 按钮
以生成、部署和运行项目。图 17 显示了该运行应用程序。
部署后,程序可执行以下功能:
- 从下拉列表中选择一个名字,并显示此人的行程摘要。
- 编辑现有的行程信息,并将更改保存到数据库中。
- 编辑具有不正确的日期格式的现有行程信息,然后单击 Add Trip 按钮添加新行,或者单击 Revert Changes 按钮放弃编辑。
- 在表中添加行,填写行程字段,并将更改保存到数据库中。
- 从表中(同时从数据库中)删除行。
-
放弃编辑内容,并恢复为数据库中最近保存的数据。
图 17:测试应用程序,第 5 部分 |
结束语
在本教程中,您将 Table 组件、Text Field 组件以及 Drop Down List 组件和数据库中的信息进行了关联。此外,还为组件设置了属性,添加了 prerender 和事件代码,从而可以插入、更新和删除数据库中的数据,并恢复在表单上输入的更改。您还使用了虚拟表单,这使得应用程序使用一个页面即可,并且在添加行或恢复更改时提交的数据可以绕过有效性检查。
更多信息