关于面试到的一题:可滚动和可更新的结果集ResultSet

需求背景

 

1.对于一个只须要分析数据的程序来讲,普通的ResultSet已够用数据库

2.但若是ResultSet用于显示一张表或查询结果的可视化数据显示,数据结构

  1)会但愿用户在结果集上先后移动的需求,spa

  2)并且一旦展现告终果集的内容,用户会但愿修改这些内容,这有两种方式:code

    (1)通常经过UPDATE语句修改(更高效)继承

    (2)经过SELECT获得ResultSet,再遍历修改(意味着能够细化修改操做!)接口

3.需求总结:细化修改操做,让用户能任意修改数据的交互程序,须要可滚动可更新的结果集ci

4.注意:不是全部的数据库驱动程序都支持可滚动可更新的结果集资源

 

 

可滚动的结果集

 

1.默认的结果集不可滚动get

2.经过在Statement建立时填入ResultSet的相关参数(type,concurrency)开启功能it

1

Statement stmt = conn.createStatement(type, concurrency);

1

PreparedStatement preStmt = conn.prepareStatement(command , type , concurrency);

 

3.ResultSet类的type值

TYPE_FORWARD_ONLY      结果集不能滚动(默认值)

TYPE_SCROLL_INSENSITIVE   结果集能够滚动,但对数据库变化不敏感

TYPE_SCROLL_SENSITIVE    结果集能够滚动,对数据库变化敏感

 

4.ResultSet类的concurrency值

CONCUR_READ_ONLY      结果集不能用于更新数据库(默认值)

CONCUR_UPDATABLE      结果集能够用于更新数据库

 

 

5.示例

 

1)只想滚动遍历结果集,而不想编辑数据

1

2

3

4

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

 

//如今调用执行获得的结果集就是可滚动的

ResultSet rs = stmt.executeQuery(query);

  可滚动的结果集有一个游标,用以指示当前位置

 

2)结果集的滚动API

(1)将游标向后移动:rs.previous()  (越界返回boolean值)

(2)相对位置:将游标向前或向后移动n行:rs.relative(n)  (n为正数向前移动,n为负数向后移动,n为0不移动,越界返回boolean值)

(3)绝对位置:将游标移动到指定行:rs.absolute(n)

(4)返回行号:int currentRow = rs.getRow()  (第一行行号是1,越界返回boolean值) 

(5)其余位置:first、last、beforeFirst、afterLast

(6)判断:isFirst、isLast、isBeforeFirst、isAfterLast

 

 

 

可更新的结果集

 

1.得到可更新的结果集

1

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

 

2.并非设置参数以后全部的查询都会返回可更新的结果集!

(1)若是查询涉及多个表的链接,那么它所产生的结果集是不可更新的;

(2)若是查询只涉及一个表,或者是使用主键链接多个表的,那么它将产生可更新的结果集;

(3)可调用ResultSet的getConcurrency方法来肯定能否更新

 

 

3.API(CRUD操做)

 

1)更新操做

(1)全部对应于SQL类型的数据类型都有updateXXX方法,与getXXX方法相似用法:必须指定列名称序号

  ()一样,这里序号指的是该列在ResultSet中的序号

(2)updateXXX改变的只是结果集中对应行的值,而非数据库中的值,当更新完行中的字段后,必需要调用updateRow方法提交到数据库中,不然全部更新操做将被丢弃

 

2)新建操做

(1)插入行:使用moveToInsertRow将游标移动到特定的位置

(2)建立行:调用updateXXX在插入行的位置上建立一个新的行

(3)回原行:调用moveToCurrentRow将游标移回到调用moveToInsetRow方法以前的位置

1

2

3

4

5

6

7

8

9

10

11

12

13

//插入行的游标位置是特定的,无需指定

rs.moveToInsertRow();

 

//在插入行插入数据

rs.updateString("Title", title);

rs.updateString("ISBN", isbn);

rs.updateString("Publisher_Id", pubid);

 

//提交建立

rs.insertRow();

 

//游标回到原来的行

rs.moveToCurrentRow();

  注意:你没法控制在结果集或数据库中添加新数据的位置;对于在插入行中没有指定值的列,将被设为NULL值,但若是有NOT NULL约束,将抛出异常且这一行是没法插入的

 

3)删除操做

1

2

//删除当前游标所指的行

rs.deleteRow();

  deleteRow会当即将该行从结果集和数据库中删除

 

4)总结

  ResultSet接口中的updateRow、insertRow和deleteRow方法 的执行效果等同于SQL命令中的UPDATE、INSERT和DELETE

 

 

 

4.应用场景示例:

(1)想提升某些图书的价格,但在执行UPDATE语句时又没有一个简单而同一个提价标准,这时须要遍从来修改,因此就用到了可滚动可更新的结果集,这时就比UPDATE灵活

1

2

3

4

5

6

7

8

9

10

11

12

13

14

String query = "SELECT * FROM Books";

ResultSet rs = stmt.executeQUERY(query);

 

while(rs.next()){

    //迭代结果集时,咱们就能够根据业务条件来细化修改

    if(...){

        double increase = 。。。

        double price = rs.getDouble("Price");

        //更改结果集中当前行的字段值

        rs.updateDouble("Price",  price + increase);

        //将更改提交到数据库,很关键不能漏

        rs.updateRow();

    }

}

 

 

优缺点

 

优势细化修改操做,让用户能任意修改数据的交互程序

 

缺点:1.在与用户的整个交互过程当中,必须始终与数据库保持链接;

  后果:当用户长时间离开时,数据库链接长时间被占用,而这属于稀缺资源;

  解决:使用行集RowSet,RowSet继承了ResultSet接口,却无需始终保持与数据库的链接~

     2.结果集不便于移动,由于数据结构复杂,且依赖于链接

  解决:使用行集RowSet,RowSet适用于将查询结果移动到复杂应用的其余层,或者其余设备当中

相关文章
相关标签/搜索