执行插入、更新和删除操作
<!-- END VNV3 PAGETITLE, two-level variation --><!-- BEGIN WRAPPER TABLE, 2 COLUMN, MAIN/RIGHT --><!-- BEGIN CENTRAL COLUMN COMPONENTS --><!--startindex--><!-- ============ --><!-- MAIN CONTENT --><!-- ============ --> <!-- BEGIN VCD4 BYLINE AND TOOLS -->2006 年 12 月 [修订号:V1-1] |
本教程介绍了如何使用 NetBeans Visual Web Pack 5.5 构建一个可以创建、检索、更新和删除数据库行的 Web 应用程序。该应用程序提供一个主数据的下拉列表以及一个同步的详细信息表。该应用程序的用户可以在详细信息表及其关联数据库中添加、更新和删除记录。 本教程使用了其他基础教程中介绍的一些概念。如果您不具备 IDE 及其设计组件的基本知识,请考虑首先阅读基础教程,如 NetBeans Visual Web Pack 5.5 入门指南 和 使用数据绑定组件访问数据库 。 |
目录
|
|
本教程将使用以下资源
NetBeans Visual Web Pack 5.5 可以与所有支持的服务器以及 Java EE 1.4 和 Java EE 5 平台配合使用。本教程向您介绍了 Visual Web Pack 的各种功能,这些功能需要利用下表中带有复选标记的资源。有关支持的服务器和 Java EE 平台的详细信息,请参见 NetBeans Visual Web Pack 5.5 安装说明 。
应用服务器 |
Sun Java System Application Server 9
Tomcat JBoss BEA WebLogic |
JavaServer Faces 组件/
Java EE 平台 |
1.2/Java EE 5*
1.1/J2EE 1.4 |
Travel 数据库 | 必需 |
BluePrints AJAX 组件库 | 不是必需的 |
* 该教程发布时,只有 Sun Java System Application Server 支持 Java EE 5。
<!-- END RESOURCE MATRIX --><!-- BEGIN EXAMPLES BOX --><!-- <table border="0" cellpadding="2" cellspacing="0"> <tr> <td> <div class="headerpadding2"><b>Example used in this tutorial</b></div> </td> </tr> <tr valign="top"> <td> <div class="headerpadding2"> » <a href="inserts_updates_deletes/insert_update_delete_ex.zip">insert_update_delete_ex.zip (zip)</a> </div> </td> </tr> </table> --><!-- END CODE EXAMPLES BOX -->创建项目
在本教程中,将创建包含一个页面的 Web 应用程序。您可以先从设计页面布局入手,该页面包含一个人名及其相应的行程,如下图所示。
<!-- BEGIN FIGURE COMPONENT -->图 1 :初始页面布局 |
-
创建一个新的 Visual Web 应用程序,并将其命名为
InsertUpdateDelete
。 -
将一个“下拉列表”组件从组件面板的“基本”类别拖动到该页的左上角。在“属性”窗口中,将其
id
属性更改为personDD
。 -
将一个“消息组”组件从组件面板的“基本”类别拖放到下拉列表的右侧。
“消息组”组件可用来显示验证错误和转换错误,以及由info()
和error()
方法写入到 Java Server Faces 上下文的消息。如果需要调试项目,这些消息将会非常有用。 - 将一个“表”组件放在这两个组件的下方。
-
打开“运行环境”窗口,展开“数据库”节点并检查是否已连接 TRAVEL 数据库。
如果 TRAVEL 数据库的 jdbc 节点标记显示为连接中断,并且无法展开该节点,则表明 IDE 未连接该数据库。要连接 TRAVEL 数据库,请右键单击 TRAVEL 数据库的 jdbc 节点,然后从弹出式菜单中选择“连接”。如果出现“连接”对话框,请输入travel
作为口令,然后单击“确定”。如果看不到 TRAVEL 数据库的 jdbc 节点,请参见 NetBeans Visual Web Pack 5.5 安装说明 以了解如何为 IDE 提供可用的数据库。 -
展开 TRAVEL 数据库的 jdbc 节点,然后展开“表”节点。
注意: 在本教程的其余部分中,将 TRAVEL 数据库的 jdbc 节点称为 "Travel" 节点。 -
将 "PERSON" 节点拖动到可视设计器的下拉列表上。
“概要”窗口的 "Page1" 部分中将显示 "personDataProvider" 节点,"SessionBean1" 部分中将显示 "personRowSet" 节点。 -
右键单击“下拉列表”组件,然后从弹出式菜单中选择“更改时自动提交”。
此设置使得每当您从列表中选择新值时,则会将该页面发送到服务器。 -
右键单击下拉列表,然后从弹出式菜单中选择“配置虚拟表单”。
在出现的对话框中,请注意personDD
显示在窗口的左上角中,这表明下拉列表已被选定。 -
单击“新建”。在“名称”列中输入
<!-- BEGIN FIGURE COMPONENT -->person
。双击“参与”列下面的字段,并将其设置为“是”,然后对“提交”列执行相同的操作,如下图所示。
图 2 :配置虚拟表单
通过使用虚拟表单,应用程序可避免对表中的数据进行不必要的验证。 - 单击“确定”。
-
单击可视设计器工具栏中的“显示虚拟表单”按钮,如图 3 所示。
通过查看虚拟表单,您可以看到可视设计器中的组件与您已经配置的任何虚拟表单之间的关系。
<!-- BEGIN FIGURE COMPONENT -->图 3 :显示虚拟表单
- 将 "Travel" >“表”> "TRIP" 节点从“运行环境”窗口拖放到可视设计器中的“表”组件上。
-
右键单击该表,然后从弹出式菜单中选择“表布局”。
该对话框显示了您刚创建的 tripDataProvider 中可用的字段,并允许您控制要在表中显示哪些字段。 -
使用 "<" 按钮,从右侧的“选定”列表中删除 TRIP.TRIPID、TRIP.PERSONID 和 TRIP.LASTUPDATED,如下图所示。
-
单击“选项”标签,并将标题更改为
Trips Summary
。 -
单击“确定”。
现在,可视设计器中的“表”组件应如下图所示。请注意,如果未按下图顺序显示各列,可通过重新打开“表布局”对话框,单击“列”标签并使用“上移”和“下移”按钮重新对其进行排列。
<!-- BEGIN FIGURE COMPONENT -->图 5 :Page1 表布局 -
在“概要”窗口中,右键单击 "SessionBean1" 下的 "tripRowSet",然后从弹出式菜单中选择“编辑 SQL 语句”。
SQL 查询编辑器将显示在编辑区域中。 -
在窗口中心附近的网格区域,在 PERSONID 行中单击鼠标右键,然后选择“添加查询条件”,如下图所示。
<!-- BEGIN FIGURE COMPONENT -->图 6 :添加查询条件 -
在对话框中,将“比较”下拉列表设置为“= 等于”并选中“参数”单选按钮,然后单击“确定”。
<!-- BEGIN FIGURE COMPONENT -->图 7 :“添加查询条件”对话框
字符 "=?" 将出现在 PERSONID 的“条件”字段中,而条件 "WHERE TRAVEL.TRIP.PERSONID=?" 则出现在编辑器底部 SQL 窗格中的 SQL 语句结尾处。 - 关闭 tripRowSet 的 SQL 编辑器。
更改列组件
-
右键单击“表”组件,然后选择“表布局”。
将打开“表布局”对话框。 -
在“列”标签中,从右侧的“选定”列表中选择 "TRIP.DEPDATE"。在对话框底部的“列详细信息”区域中,将“组件类型”从“静态文本”更改为“文本字段”,如下图所示。
<!-- BEGIN FIGURE COMPONENT -->图 8 :更改列的外观 - 对 TRIP.DEPCITY 和 TRIP.DESTCITY 执行相同的操作。
- 在“选定”列表中选择 "TRIP.TRIPTYPEID",然后将“组件类型”从“静态文本”更改为“下拉列表”。
-
单击“确定”。
注意: 如果执行上述步骤后表列太宽,则可以通过选择每列中的第一个组件并拖动其选择句柄来调整列的大小。 -
将 "Travel" >“表”> "TRIPTYPE" 节点拖动到“表”组件中的下拉列表上。
此操作将创建triptypeDataProvider
。
为表配置虚拟表单
- 在可视设计器中,使用 Ctrl 键的同时单击“表”组件中的三个“文本字段”组件和一个“下拉列表”组件。右键单击其中一个选定的组件,然后从弹出式菜单中选择“配置虚拟表单”。
- 在“配置虚拟表单”对话框中,确保窗口左上角列出了三个文本字段和一个下拉列表。如果未按下图所示的方式列出这些内容,请关闭对话框,重新选择它们,然后再试一次。如果已正确列出这些内容,则单击“新建”。
-
将新虚拟表单的名称更改为
<!-- BEGIN FIGURE COMPONENT -->save
,将“参与”设置更改为“是”(如下图所示),然后单击“确定”以关闭窗口。图 9 :为表元素配置虚拟表单
添加事件代码和初始化代码
- 双击 personDD 下拉列表以创建值更改事件方法(将打开 Java 编辑器,并且插入点将位于该方法内)。
-
在值更改事件方法中,找到注释行
<!-- BEGIN CODE SAMPLE COMPONENT -->// 待做事项:替换为您的代码
。使用代码样例 1 中的粗体文本替换此行。代码样例 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
方法,当出现错误时就会将消息显示在“消息组”组件中。 -
在 Java 源代码中滚动至
<!-- BEGIN CODE SAMPLE COMPONENT -->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 编辑器中单击鼠标右键,然后选择“重新设置代码格式”以便对代码进行适当的排列。
测试应用程序 - 第 1 部分
在主工具栏上单击“运行主项目”按钮以生成、部署和运行项目。当 Web 浏览器呈现此页面时,您会看到一些名字填充了下拉列表,并且表也由一些数据进行了填充。当您从列表中选择其他名字时,与该名字关联的行程将会显示在表中。
<!-- BEGIN FIGURE COMPONENT -->图 10 :部署的应用程序,测试 1 |
添加插入功能
- 在可视设计器中查看 Page1。
- 在组件面板的“基本”类别中,将“消息”组件分别拖动到表的前三列中最上面的文本字段上。
-
选择第一个“消息”组件。在“属性”窗口中,滚动至
for
属性,然后从下拉列表中选择textField1
。只有当消息与文本字段正确关联时,消息文本才会显示关联信息,如图 11 所示。 -
选择第二个“消息”组件并将其
for
属性设置为textField2
。 -
将第三个“消息”组件的
<!-- BEGIN FIGURE COMPONENT -->for
属性设置为textField3
。图 11 :将“消息”组件与文本字段关联 - 在组件面板的“基本”类别中,将一个“按钮”组件拖动到 Page1 上,并将它放置在“表”组件上方靠近第二列的顶部,如图 12 所示。
-
将其 text 属性由“
按钮
”更改为 "Add
Trip
"。 -
在“属性”窗口中,将按钮的
id
属性更改为add
。 - 在可视设计器中,双击该按钮以打开 Java 编辑器,插入点将位于该按钮的事件处理程序中。
-
修改按钮的事件代码(
<!-- BEGIN CODE SAMPLE COMPONENT -->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 编辑器中单击鼠标右键,然后选择“修复导入”以解决“找不到
RowKey
”的错误。IDE 将在
Page1.java
的 import 语句块中添加下列包:import com.sun.data.provider.RowKey;
测试应用程序 - 第 2 部分
生成、部署和运行项目。当 Web 浏览器呈现此页面时,将显示 "Add Trip" 按钮,如下图所示。每次单击该按钮时,都会在表的底部附加一个新的空行。您可以编辑行中的信息,但由于尚未提供行集的保存机制,因此,从下拉列表中选择其他名字时,所做的更改将会丢失。
<!-- BEGIN FIGURE COMPONENT -->图 12 :部署的应用程序,测试 2 |
修改页面以保存行集
- 在编辑器窗口中单击 "Design" 以返回到可视设计器中的 Page1。
-
从“运行环境”窗口中选择“数据库”> "Travel" >“表”> "TRIP" 表,然后将它拖动到“概要”窗口中的 "SessionBean1" 节点上。
<!-- BEGIN FIGURE COMPONENT -->图 13 :将 TRIP 表拖动到 SessionBean1 上
此操作将会打开“添加新的数据提供器”对话框。 -
单击“创建 SessionBean1/tripRowSet1”单选按钮,将数据提供器的名称更改为
maxTripRowSet
,然后单击“确定”。注意: 行集在对话框中出现了两次。这是一个已知问题,请予以忽略。它不会影响本教程中的应用程序。
<!-- BEGIN FIGURE COMPONENT -->图 14 :将新的数据提供器添加到 SessionBean1 中
此操作将在 SessionBean1 中创建 maxTripDataProvider 和 maxTripRowSet。 -
在“概要”窗口中,双击 "SessionBean1" > "maxTripRowSet" 以打开查询编辑器。在源代码窗格(上数第三个窗格)中单击鼠标左键。删除此处现有的 SQL 查询,然后输入以下查询:
SELECT MAX(TRAVEL.TRIP.TRIPID)+1 AS MAXTRIPID FROM TRAVEL.TRIP
MAXTRIPID
值将用在 "Save" 按钮(接下来,将添加此按钮)的操作处理程序中。 - 关闭查询编辑器。请注意,查询编辑器的图形编辑器不支持此查询。如果您看到一个提示出现语法错误的警报对话框,可通过单击“继续”安全地将其关闭。
- 将一个“按钮”组件放在表的第一列上方。
-
将按钮的 text 属性由“按钮”
更改为 "
Save Changes
"。 -
在“属性”窗口中,将其
id
属性更改为save
。 - 右键单击 "Save Changes" 按钮,然后从弹出式菜单中选择“配置虚拟表单”。
-
在“配置虚拟表单”对话框中,确保左上角的列表中显示的是
save
,以便此窗口中的更改可以应用于 "Save Changes" 按钮。然后,选择save
虚拟表单,将“提交”值更改为“是”并单击“确定”。 - 在可视设计器中,双击 "Save Changes" 按钮以打开 Java 编辑器。在 Java 编辑器中,插入点将位于该按钮的事件处理程序中。
-
修改该按钮的事件代码(
<!-- BEGIN CODE SAMPLE COMPONENT -->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")).intValue(); // 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 部分
通过单击“运行主项目”按钮以生成、部署和运行项目。应用程序将可以实现以下功能:
- 可以添加行程并进行保存。行程将会显示在表中,并且在选择其他人员后重新返回时,该行程仍然存在。
- 可以编辑现有的行程信息,并保存所做的更改。
- 如果在 "Date" 字段中输入除日期之外的内容,则应用程序将提供一条错误消息。
- 在保存之前可以多处单击 "Add Trip",这是一次添加多行的简便方法。
- 如果在保存之前切换到其他人员,则会丢失所有更新(包括在所添加的行上正在填写的信息)。
- 如果修改了某些值,然后单击某个列标题(使之按该列进行排序),则表组件会记住这些暂挂的更改,并在随后可以保存这些更改。
添加删除功能
<!-- InsertUpdateDelete12-TP3.zip -->
现在,将删除功能添加到表中。利用此功能,用户能够通过从数据库中删除某行来删除行程。在本教程中,"Delete" 按钮的操作是即时的,并且从数据库中删除行时并不需要使用 "Save Changes" 按钮。实际上,由于 "Delete" 按钮的事件处理程序使用
commitChanges()
方法,因此它也像 "Save Changes" 按钮一样保存所有暂挂的更改。
-
在可视设计器中,右键单击“表”组件,然后从弹出式菜单中选择“表布局”。
将打开“表布局”对话框。 - 单击“列”标签,然后单击“新建”,将一个新列添加到表中。
-
在“选定”列表中选择新列的名称后,在“列详细信息”区域中进行如下更改:
- 表头文本和页脚文本: <删除“表头文本”字段和“页脚文本”字段中的任何缺省文本,使其保持空白>
-
组件类型:
按钮
-
值表达式:
Delete
- 宽度: <删除任何缺省值,使其保持空白>
-
水平对齐:
居中
-
垂直对齐:
居中
- 单击“确定”
-
选择位于表中最上面的 "Delete" 按钮,并在“属性”窗口中将
id
属性设置为delete
。
-
双击 "Delete" 列中的第一个按钮,将打开 Java 编辑器,且插入点位于
delete_action()
事件处理程序中。 -
更改
delete_action()
方法,使其如下所示:代码样例 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 部分
通过单击“运行主项目”按钮以生成、部署和运行项目。下图显示了运行的应用程序。
部署后,您应该可以从表中删除行,进而将其从数据库中删除。删除操作还会将所有暂挂的更改提交到数据库中。
<!-- BEGIN FIGURE COMPONENT -->图 15 :测试应用程序,第 4 部分 |
添加恢复功能
<!-- InsertUpdateDelete12-TP4.zip -->现在,将恢复功能添加到页面中。使用此功能,用户可以放弃其编辑的内容,恢复为以前保存的数据。请注意,恢复功能并不能恢复已保存或已删除的行;因为 "Save Changes" 和 "Delete" 按钮会将更改提交到数据库中。
- 在可视设计器中,将一个“按钮”组件从组件面板拖动到 Page1 上。将新的按钮放在 "Add Trip" 按钮的右侧。
-
将按钮的 text 属性更改为
Revert
Changes
。 -
在“属性”窗口中,将“按钮”组件的
id
属性更改为revert
。 -
双击 "Revert Changes" 按钮,将打开 Java 编辑器,且插入点会位于
revert_action()
方法中。 -
将下面代码样例中以粗体显示的代码添加到
<!-- BEGIN CODE SAMPLE COMPONENT -->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" 按钮,操作将会失败。由于日期转换错误拒绝提交表单,因此不会将任何新行添加到表中。理想的行为是先处理表中的输入字段,以便在忽略现有行的暂挂内容的情况下添加新行。
同样,当用户单击 "Delete" 按钮删除行时,不论对该行或其他现有行进行了哪些编辑,都应该删除该行。而当用户单击 "Revert" 按钮时,其目的是放弃所有编辑的内容,这又应该忽略以上情况的编辑内容。
-
在可视设计器中,选中 "Add"、"Delete" 和 "Revert" 按钮,单击鼠标右键,然后从弹出式菜单中选择“配置虚拟表单”。
在“配置虚拟表单”窗口中,add
、delete
和revert
应该出现在其左上角,以表示这些按钮处于选定状态。 -
在“配置虚拟表单”窗口中,单击“新建”,将新的虚拟表单命名为
<!-- BEGIN FIGURE COMPONENT -->add/delete/revert
,然后将“提交”设置为“是”。单击“确定”。图 16 :为 "Add"、"Revert" 和 "Delete" 按钮配置虚拟表单
测试应用程序 - 第 5 部分
通过单击“运行主项目”按钮以生成、部署和运行项目。下面的图 17 显示了正在运行的应用程序。
部署后,程序可执行以下功能:
- 从下拉列表中选择一个名字时,会显示出此人的行程摘要。
- 编辑现有的行程信息,并将更改保存到数据库中。
- 在表中添加行,填写行程字段,并将更改保存到数据库中。
- 从表中(同时从数据库中)删除行。
-
放弃编辑内容,并恢复为数据库中最近保存的数据。
图 17 :测试应用程序,第 5 部分 |
小结
在本教程中,您将表组件、文本字段组件和下拉列表组件与数据库中的信息进行了关联;此外,为组件设置了属性,添加了 prerender 和事件代码,从而可以插入、更新和删除数据库中的数据并恢复所做的更改。您还使用了虚拟表单,这使得应用程序使用一个页面即可,并且提交数据时绕过了有效性检查。
FROM:http://www.netbeans.org/kb/55/vwp-inserts_updates_deletes_zh_CN.html