第9章 数据库操作
本章学习目标:
l 掌握NetBeans中数据库应用开发的基本过程;
l 掌握NetBeans中数据库常用操作的实现。
主要内容:
l 创建应用需要的数据库表;
l 通过可视化界面显示数据库表中所有的信息;
l 在此基础上对这些信息进行修改和删除;
l 实现添加功能;
l 根据条件查询信息;
l 使用MySQL数据库作为应用数据库。
9.1 准备工作
9.1.1 目标
使用NetBeans自带的数据库管理系统创建后续章节将要使用的数据库,数据库的名字为jsfdb,然后在该数据库中物品表goods,并添加测试数据。
9.1.2 跟着我操作
1)创建数据库
主菜单中选择:【Tools】à【Java DB Database】à【Create Database】。
在弹出的界面中,设置数据库的名字为“jsfdb”,用户名为“jsf”,口令为“jsf”,如图所示,然后点击【OK】。
图9.1 创建数据库
2)连接数据库
在Service下面的Databases下面可以看到已经建立好的到数据库jsfdb的连接,连接的名字为:jdbc:derby://localhost:1527/jsfdb。在该连接上点击右键,可以通过【Properties】察看属性。要连接到这个数据库,在这个URL上点击右键,选择【Connect…】即可。如图所示:
图9.2 连接数据库
数据库连接之后,可以看到有3个字文件夹,分别是Tables、Views和Procedures。现在全部为空。
3)创建数据表
可以通过两种方式创建表:可视化方法和命令行方式(写SQL语句)。
可视化创建表的过程:在“Tables”上面点击右键,然后选择【Create Table…】,然后在弹出的表设计界面中设计表,这个过程可以自行完成,不再介绍。
通过命令行的方式创建表:在“Tables”上点击右键,然后选择【Execute Command…】,
在右边的界面中输入创建表的语句:
create table goods
(
goodid varchar(10) primary key,
goodname varchar(20) not null,
price float
)
在下面的【output】窗口中显示执行成功。执行成功之后看不到创建的表,需要在“Tables”上点击右键,选择【Refresh】,就可以看到创建的表。如图所示:
图9.3 创建表
4)插入测试数据
在命令行窗口中继续执行下面的SQL语句:
insert into goods values('0011002200','洗衣粉',18);
insert into goods values('0011002201','香皂',3.5);
insert into goods values('0011003300','香油',10);
insert into goods values('0011003301','酱油',2.8);
insert into goods values('0011004400','花生',11);
insert into goods values('0011004401','瓜子',5);
insert into goods values('0011005500','面粉',23);
insert into goods values('0011005501','大米',17);
5)察看数据
在表GOODS上面点击右键,选择【View Data】,即可查看数据。
9.2 显示所有数据
9.2.1 目标
把物品表中的信息显示在界面上。
9.2.2 跟着我操作
1)创建工程
创建可视化Web应用,应用的名字为:dbtest。
2)创建JSF页面
使用创建Web应用时候生成的JSF页面Page1.jsp作为显示信息的界面。
3)向页面添加组件
u 在页面的上方添加一个Label控件,然后输入“物品信息列表”。
u 在标签的下面添加Table控件。
4)连接到数据库
在Runtime窗口中,选择配置好的要连接的数据库URL,展开这个连接,如果不能展开,说明还没有连接,先建立连接,可以参考前面介绍的连接数据库。
u 展开Databases节点;
u 展开Tables节点;
u 选择Goods表;
u 然后把表Goods表拖到表格上;
之后的界面如图所示:
图9.4 物品信息列表设计界面
5)运行程序
在工程上点击右键,选择【Run】。这时候IDE会完成如下工作:
启动服务器;
把应用部署到服务器上;
启动浏览器,访问服务器上的应用。
运行效果如下:
图9.5 运行结果
【试一下】点击表头的GOODID、GOODNAME和PRICE,看看有什么变化?
9.2.3 告诉您为什么
1)在图4中的列表中abc和123.0表示什么
在设计界面上,列表中会显示abc,这个abc表示显示的信息与一个String对象关联,在这种情况下,与SQL类型为varchar的数据库列对应。同样123.0表示显示的信息与一个Double对象关联。
2)Table组件如何与数据库表关联
IDE为数据库表添加了一个不可见的组件goodsDataProvider组件,这个组件在Navigator窗口中可以看到。同时IDE在SessionBean1中添加了一个属性goodsRowSet。
goodsRowSet属性保存了从数据库中得到的物品信息,连接数据库并封装数据的过程由IDE生成的代码完成,开发人员不需要关心,如果想修改查询结果,只要对SQL语句进行修改即可。在Navigator窗口中,选择SessionBean1下面的goodsRowSet,然后点击右键,在弹出式菜单中选择【Edit SQL Statement】,如图所示:
图9.6 选择编辑SQL语句
之后弹出如图所示的界面:
图9.7 SQL编辑区
上面显示了表的结构,中间部分显示的是SQL语句的可视化设计界面,下面部分是SQL语句的代码编辑区。
goodsDataProvider是数据提供者,与SessionBean1中的goodsRowSet相关联,可以通过下面的方式查看。
在navigator窗口中选择Page1下的GoodsDataProvider,然后在右边的属性窗口中可以查看GoodsDataProvider属性,如下图,cachedRowSet的值就是前面介绍的SessionBean1中的goodsRowSet。
图9.8 数据提供者与行集的关联
Table组件与goodsDataProvider数据提供者关联。右键点击Table组件,在弹出式菜单中选择Bind to Data,会显示Bind to Data对话框,如下图所示:
图9.9 数据绑定对话框
Table组件具体显示什么数据,可以在Table上点击右键,选择【Table Layout】,弹出如图所示界面:
图9.10 Table Layout界面
可以通过Available和Selected列表框中间的左右箭头选择要显示那些列的信息。如果希望修改某一列的相关属性,可以先在Selected列表框中选中该列,然后修改下面的属性。
3)系统如何访问数据库
在工程的Server Resources下面的sun-resources.xml中有连接池和数据源的配置代码:
<jdbc-resource enabled="true" jndi-name="jdbc/JSF_ApacheDerby" object-type="user" pool-name="derby_netPool"/>
<jdbc-connection-pool
allow-non-component-callers="false"
associate-with-thread="false"
connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-leak-reclaim="false"
connection-leak-timeout-in-seconds="0"
connection-validation-method="auto-commit"
datasource-classname="org.apache.derby.jdbc.ClientDataSource"
fail-all-connections="false"
idle-timeout-in-seconds="300"
is-connection-validation-required="false"
is-isolation-level-guaranteed="true"
lazy-connection-association="false"
lazy-connection-enlistment="false"
match-connections="false"
max-connection-usage-count="0"
max-pool-size="32"
max-wait-time-in-millis="60000"
name="derby_netPool"
non-transactional-connections="false"
pool-resize-quantity="2"
res-type="javax.sql.DataSource"
statement-timeout-in-seconds="-1"
steady-pool-size="8"
validate-atmost-once-period-in-seconds="0"
wrap-jdbc-objects="false">
<property name="serverName" value="localhost"/>
<property name="PortNumber" value="1527"/>
<property name="DatabaseName" value="jsfdb"/>
<property name="User" value="jsf"/>
<property name="Password" value="jsf"/>
</jdbc-connection-pool>
在工程的web.xml中有如下的代码:
<resource-ref>
<description>Creator generated DataSource Reference</description>
<res-ref-name>jdbc/JSF_ApacheDerby</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
goodsRowSet对象访问上面的数据源。在SessinBean1中,会看到_init方法中有如下的代码:
goodsRowSet.setDataSourceName("java:comp/env/jdbc/JSF_ApacheDerby");
goodsRowSet.setCommand("SELECT * FROM JSF.GOODS");
goodsRowSet.setTableName("GOODS");
9.3 完成添加功能
9.3.1 目标
本节的目标如下:
l 能够通过界面向数据库中添加信息;
l 能够通过界面修改数据库中的信息;
l 能够撤销这些修改。
9.3.2 跟着我操作
1)编写界面
在界面上添加一个按钮,输入“添加物品”,当点击这个按钮的时候会在表格下面添加一行。
然后界面上再添加一个按钮,输入“保存修改”,当点击这个按钮的时候系统会保存修改后的信息。
2)修改Table中的元素
Table中原来显示信息使用静态文本,现在需要修改成输入框以便使用。
在Table上点击右键,选择【Table Layout】,在弹出的界面上选择Selected列表框中的GOODS.GOODID,然后修改下面的Component Type属性后的下拉框,选择“Text Field”。
采用同样的方法修改另外两个属性。
3)创建虚拟表单
按住Ctrl键,选择表格中最上面的3个输入框。然后在任意输入框上右键点击,在弹出式菜单中选择【Configure Virtual Forms...】,出现下面的界面:
图9.11 编辑虚拟表单
把Name修改为“save”,选择Participate为Yes,然后点击【OK】即可。
4)为“添加物品”按钮添加动作
当点击“添加物品”按钮的时候,会在Table的下面添加一行。添加动作的过程如下:
点击“添加物品”按钮,IDE会打开源代码并生成button1_action方法;
修改方法如下(粗体为添加部分):
public String button1_action() {
try {
RowKey rk = goodsDataProvider.appendRow();
goodsDataProvider.setCursorRow(rk);
} catch (Exception ex) {
log("Error Description", ex);
error(ex.getMessage());
}
return null;
}
5)为“保存修改”按钮添加动作
当点击“保存修改”按钮的时候,会把用户的修改更新到数据库中。添加处理代码的过程如下:
点击“保存修改”按钮,IDE会打开源代码并生成button2_action方法;
修改方法代码如下(粗体为添加部分):
public String button2_action() {
try {
goodsDataProvider.commitChanges();
} catch (Exception ex) {
log("Error Description", ex);
error("Error :"+ex.getMessage());
}
return null;
}
6)运行测试
7)取消操作
l 在界面上添加一个按钮;
l 修改按钮的内容为“取消改变”;
l 把按钮的id属性修改为“cancle”;
l 双击该按钮,生成action事件;
l 为事件添加处理代码:
public String revert_action() {
form1.discardSubmittedValues("save");
try {
goodsDataProvider.refresh();
} catch (Exception ex) {
log("Error Description", ex);
error(ex.getMessage());
}
return null;
}
9.3.3 告诉您为什么
1)修改功能是如何实现的
通过前面的介绍,修改功能的操作过程为:修改表格中的某一行,然后点击“保存修改”即可完成,该功能是如何实现的呢?
表格中的数据与goodsDataProvider关联,当修改表格中的数据之后,修改后的数据也会映射到goodsDataProvider;
当点击“保存修改”的时候,调用了goodsDataProvider的commitChanges方法;
该方法能够调用goodsRowSet的相应方法完成对数据库中数据的更新。
2)添加功能是如何实现的
添加功能与修改功能的实现非常类似,只是需要先在表格中添加一行,通过下面的代码添加:
RowKey rk = goodsDataProvider.appendRow();
3)撤销功能是如何实现的
不管是添加功能还是修改功能,用户操作完之后,都需要通过goodsDataProvider对象的commitChanges方法完成提交。如果不提交,这些修改不会影响到goodsRowSet对象。
如果不想要这些修改,可以调用goodsDataProvider的refresh方法进行刷新,会从goodsRowSet中重新加载数据,这样用户在表格中所作的修改就撤销了。
9.4 完成删除功能
9.4.1 目标
在信息列表界面中,当用户选择某个记录后面的删除按钮的时候,可以删除当前记录。
9.4.2 跟着我操作
1)修改界面
首先在表格的每一行添加一个删除按钮,操作过程如下:
l 在Table上点击右键,选择Table Layout;
l 点击New按钮添加一列;
l 选中该列;
l 修改该列的相关信息,如图12所示;
l 点击OK即可。
图9.12 为表格添加列
2)为删除按钮添加事件
双击表格中的删除按钮生成事件方法;
添加事件处理代码:
public String delete_action() {
form1.discardSubmittedValues("save");
try {
RowKey rk = tableRowGroup1.getRowKey();
if (rk != null) {
goodsDataProvider.removeRow(rk);
//goodsDataProvider.commitChanges();
//goodsDataProvider.refresh();
}
} catch (Exception ex) {
log("ErrorDescription", ex);
error(ex.getMessage());
}
return null;
}
代码中首先得到要删除的行,然后调用goodsDataProvider的romoveRow方法删除。如果希望立即删除可以调用goodsDataProvider的commitChanges方法完成提交。
9.5 按条件查询
9.5.1 目标
查找价格大于某个数字的商品:在界面上输入一个价格,然后点击“查询”显示所有满足条件的商品。
9.5.2 跟着我操作
1)编写界面
在界面上需要添加一个查询的提示信息,查询所使用的输入框,和查询按钮,操作过程如下:
l 在界面上添加静态文本:“按价格查询:价格大于”;
l 在静态文本的右边添加输入框,并设置长度为8,修改id为min;
l 在输入框后面添加按钮,修改内容为“查询”,修改id为find。
2)修改查询语句
操作过程如下:
l 选择SessionBean1下面的goodsRowSet;
l 右键点击,选择Edit SQL Statement,进入编辑界面,如图7所示;
l 选中price行,在Criteria上点击右键,点击弹出的“Add Query Criteria”,弹出“Add Query Criteria”对话框;
图9.13 添加查询条件
l 在“Add Query Criteria”对话框中设置如下:
n 在“Comparison”下拉框中选择“>Greater Than”;
n 选择“Parameter”单选按钮;
l 点击“OK”即可。
图9.14 添加查询条件对话框
确定之后,会看到代码区中的代码已经发生变化(粗体为修改部分):
SELECT ALL "JSF"."GOODS"."GOODID",
"JSF"."GOODS"."GOODNAME",
"JSF"."GOODS"."PRICE"
FROM JSF.GOODS
WHERE "JSF"."GOODS"."PRICE" > ?
3)编写处理代码
双击“查询”按钮,生成find_action方法,修改方法体如下:
public String find_action() {
try{
String minValue = (String)min.getText();
int iMinValue = Integer.parseInt(minValue);
this.getSessionBean1().getGoodsRowSet().setInt(1,iMinValue);
goodsDataProvider.refresh();
}catch(Exception ex){
log("ErrorDescription", ex);
error(ex.getMessage());
}
return null;
}
4)编写初始化代码
因为第一次访问页面的时候没有查询条件,这时候goodsRowSet中的SQL语句中的变量就没有办法赋值,如果直接运行将差生错误,所以需要对查询进行初始化,通常在呈现之前进行初始化,可以通过prerender方法完成。
可以通过查找功能,查找到prerender方法,查找到之后修改方法如下:
public void prerender() {
if(this.getMin().getValue()==null)
try{
this.getSessionBean1().getGoodsRowSet().setInt(1,-1000);
goodsDataProvider.refresh();
}catch(Exception ex){
log("ErrorDescription", ex);
error(ex.getMessage());
}
}
9.5.3 告诉您为什么
1)Text控件的getText方法返回值类型
Text控件的返回值类型为Object,所以在得到这个值的时候需要先进行强制类型转换,如下面的代码:
String minValue = (String)min.getText();
2)通过prerender方法进行初始化
如果需要对界面中的组件进行初始化,应该在prerender方法中完成。该方法在呈现阶段之前执行。
3)对SQL中参数赋值
可以通过CashedRowSet对象的各种set方法完成参数的初始化。下面是对不同类型参数赋值的例子:
l 整型参数:setInt,第一个参数是参数的索引号或者参数名字,第二个参数是值;
l 字符串参数:setString,第一个参数同上,第二个参数是值;
l 日期参数:setDate
l 浮点型参数:setFloat
l 双精度类型:setDouble
9.6 其它的数据库常用操作
常用的功能包括设置游标的位置和当前记录信息的获取。
9.6.1 设置游标的位置
通过DataProvider对象的方法完成光标位置的设置:
把光标放在第1条记录上:cursorFirst();
把光标放在最后1条记录上:cursorLast();
把光标放在下1条记录上:cursorNext();
把光标放在前1条记录上:cursorPrevious();
把光标放在特定记录上:setCursorRow(RowKey rk);
9.6.2 获取当前记录的相关信息
如果需要获取当前记录的信息,可以通过下面的方法实现:
得到记录数:getRowCount
得到当前行:getCursorRow
得到某一列的类型:getType,参数是String类型的列名,或者是FieldKey类型对象
得到某一列的值:getValue,参数是String类型的列名,或者是FieldKey类型的对象
得到某一行:getRowKey,参数是列的编号
9.7 使用MySQL数据库
在应用中都会采用适合自己项目的数据库,如果不使用NetBeans自带的数据库,可以配置使用其它的数据库,下面以MySQL为例介绍其它数据库的使用方法。
主要过程包括:
l 加载驱动程序;
l 创建连接;
l 使用。
使用过程与前面介绍的NetBeans自带的数据库的使用方式没有区别,主要是加载驱动程序和创建连接的过程不一样。下面分别介绍:
9.7.1 加载驱动程
加载驱动程的过程如下:
l 在Databases节点下的Drivers节点上点击右键,选择New Driver…,如图13所示;
l 点击右上角的Add…按钮,打开“选择文件”对话框,选择驱动程序所在的压缩包,然后确定,注意驱动程序的版本。
l 如果系统能够识别驱动程序,在会把驱动程序的名字显示在Driver Class后面的下拉框中,如果不能识别,在Driver Class中输入驱动程序的名字,或者通过Find按钮查找驱动程序Driver类。
l 在Name中输入一个名字,后面会使用。
l 选择OK即完成驱动程序的加载。
图9.15 添加驱动程序对话框
9.7.2 创建连接
创建连接的过程如下:
l 在Databases上点击右键,选择New Connection。
l 在弹出的New Database Connection对话框中输入连接的相关信息,几乎连接所有的数据库所需要的信息是相同的。信息如下:
n Name:要使用的驱动程序的名字;
n Driver:与该改上面的名字对应的驱动程序类的名字;
n Databese URL:访问数据库的URL,格式与具体的驱动程序有关,是由驱动程序解析的。
表9.1 常用数据库服务器的默认端口
数据库类型 | 端口 |
Oracle 9 | 1521 |
Java DB Database | 1527 |
Microsoft SQL Server | 1433 |
Sybase | 5000 |
DB2 | 5000 |
MySQL | 3306 |
n User name:连接数据库的用户名;
n Password:用户名对应的口令。
n Remember password during this session复选框:如果要保存口令,可以选择。
l 然后点击OK即可。
创建完之后,后在Databases下面会显示创建好的连接。