(六) 可滚动和可更新的结果集

当用于显示一张表或查询结果的可视化数据显示时,ResultSet类中的next方法无法满足在结果集上前后移动。

6.1 可滚动的结果集
Statment : Statment stmt = conn.createStatment(type, concurrency);
PreparedStatement : PreparedStatement prepStmt = conn.prepareStatement(command, type, concurrency);

 

                ResultSet的type值
TYPE_FORWARD_ONLY               结果集不能滚动
TYPE_SCROLL_INSENSITIVE     结果集可以滚动,但对数据库的变化不敏感
TPYE_SCROLL_SENSITIVE         结果集可以滚蛋,且对数据库的变化敏感

                ResultSet的Concurrency值
CONCUR_READ_ONLY               结果集不能用于更新数据库(默认值)
CONCUR_UPDATABLE                结果集可以用于更新数据库

 

e.g.如果只想滚动遍历结果集,而不想编辑它的数据
    Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    ResultSet result = stmt.executeQuery(query);
这样得到的ResultSet结果集都将是可滚动的。
注意 :
(1)可滚动的结果集只有一个光标,用以指示当前位置。
(2)并非所有的数据库驱动程序都支持可滚动和可更新的结果集。通过conn.getMetaData()返回的DatabaseMetaData类中的supportsResultSetType(int type)和supportsResultSetConcurrency(int type, int concurrency)方法,可以知道特定的驱动程序是否支持哪些结果集。
(3)即使是数据库支持所有的结果集,某个特定的查询也有可能无法产生带有所有请求的所有属性的结果集(比如,一个复杂的查询结果,就有可能是不可更新的),此时executeQuery方法将返回一个功能较少的ResultSet对象,并添加一个SQLWaring给连接对象。
(4)也可以使用ResultSet类中的getType和getConcurrency方法查看结果集实际支持的模式。
(5)如果不进行检查并发起一个不支持的操作,比如对不可滚动的结果集调用previous,将抛出SQLException异常。

在结果集上进行滚动:
(1)boolean previous() : 将光标移动到此 ResultSet 对象的上一行。 如果游标位于一个实际位置返回true,如果位于第一行之前,返回false。
(2)boolean relative(int rows) : 按相对行数(或正或负)移动光标。正数为向下滚动游标,负数为向上滚动游标。调用方法 relative(1) 等效于调用方法 next(),而调用方法 relative(-1) 等效于调用方法 previous(),调用 relative(0) 有效,但是不更改光标位置。如果光标位于行上,则返回 true;否则返回 false。
(3)boolean absolute(int row) : 将光标移动到此 ResultSet 对象的给定行编号。
(4)int getRow() : 获取当前行编号。结果集中第一行的行号为1,如果不存在当前行,则返回 0,即不在任何行上。
(5)boolean first : 将光标移动到此 ResultSet 对象的第一行。
   boolean last : 将光标移动到此 ResultSet 对象的最后一行。
   void beforeFirst() : 将光标移动到此 ResultSet 对象的开头,正好位于第一行之前。
   void afterLast() : 将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
(6)boolean isFirst() : 获取光标是否位于此 ResultSet 对象的第一行。  
   boolean isLast() : 获取光标是否位于此 ResultSet 对象的最后一行。
   boolean isBeforeFirst() : 获取光标是否位于此 ResultSet 对象的第一行之前。
   boolean isAfterLast() : 获取光标是否位于此 ResultSet 对象的最后一行之后。
     
6.2 可更新结果集
如果希望编辑结果集中的数据,并且将结果集上的数据变更自动反映到数据库中,那么就必须使用可更新的结果集。可更新的结果集并不一定是可滚动的,但如果将数据提供给用户去编辑,那么通常也会希望结果集是可滚动的。

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
这样调用executeQuery方法返回的结果集就是可更新的结果集。

注意 :
(1)并非所有的查询都会返回可更新的结果集。如果查询涉及多张表的连接操作,那么它所产生的结果集将是不可更新的。
(2)如果查询只涉及一张表,或在查询时是使用主键连接多个表格,那么产生的结果集将是可更新的结果集。
(3)通过调用ResultSet类中的getConcurrency concurrency方法来确定结果集是否是可更新的。

更新
(1)所有对应于SQL类型的数据类型都配有updateXXX方法,比如updateDouble、updateString等。使用方式与getXXX相同,必须指定列的名称或序号。
(2)updateXXX方法只是改变结果集中的行集,而非数据库中的值。当更新完行中的字段值后,必须调用updateRow方法,该方法将当前行中所有更新信息发送给数据库。
(3)如果没有调用updateRow方法就将光标移动到其他行上,那么所有的更新信息都将被行集丢弃,而且永远不会传递给数据库。
(4)可以调用cancelRowUpdates方法来取消对当前行的更新。

添加
(1)使用moveToInsertRow方法将光标移动到特定的位置,称之为插入行(insert row)。
(2)调用updateXXX方法在插入行的位置上创建一个新的行。
(3)调用insertRow方法将新建的行发送给数据库。
(4)完成插入操作后,调用moveToCurrentRow方法将光标移回到调用moveToInsertRow方法之前的位置。
e.g.通过可更新集插入一条数据。
    rs.moveToInsertRow();
    rs.updateString("name", name);
    rs.updateInt("age", age);
    rs.insertRow();
    rs.moveToCurrentRow();
注意:
(1)无法控制在结果集或数据库中添加新数据的位置。
(2)对于在插入行中没有指定值的列,将被设置为SQL的null。但,如果这个列有NOT NULL约束,那么将抛出异常,并且改行插入失败。

删除
deleteRow方法会立即将该行从结果集和数据库中删除
e.g.立即删除结果集合数据库中的当前行
    rs.deleteRow();

结果集中需要的注意事项:
(1)ResultSet类中的updateRow、insertRow和deleteRow方法的执行效果等同于SQL命令中的UPDATE、INSERT和DELETE。
(2)需要小心处理结果集,否则在使用可更新的结果集时编写非常低效的代码。
(3)执行UPDATE语句,要比建立一个查询,然后一边遍历一边修改数据显的高效的多(减少了连接数据库的次数)。
(4)对大多数的程序性的修改而言,使用SQL的UPDATE语句更合适一些。
(5)JDBC2中对结果集做了进一步的改进,例,如果数据被其他的并发数据库连接所修改,那么它可以用最新的数据来更新结果集。  
(6)JDBC3中添加了另一种优化,可以指定结果集在事物提交时的行为。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值