【0】README

1) 本文部分文字描述转自 core java volume 2 , 测试源代码均为原创, 旨在理解 java数据库编程——可滚动和可更新的结果集 的基础知识 ;
2)for database connection config, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/database.properties
3)用户通常希望在结果集上前后滚动。在可滚动结果集中, 可以在其中向前或向后移动, 甚至可以跳过任意位置;


【1】可滚动结果集

1)默认情况,结果集是不可滚动的;

  • 1.1)为了从查询中获得可滚动的结果集, 必须使用下面的方法得到一个不同的Statement 对象:
    Statement stat = conn.createStatement(type, concurrency); (干货——获得滚动的结果集)
  • 1.2)如果要获得预备语句, 请调用下面的方法:
    PreparedStatement stat = conn.preparedStatement(command, type, concurrency);

Attention)下表列出了 type 和 concurrency 的所有可能值:

  • A1)是否希望结果集是滚动的?
  • A2)如果结果集是滚动的, 且数据库在查询生成结果集后发生了变化, 那么是否希望结果集反应出这些变化?
  • A3)是否希望通过编辑结果集就可以更新数据库?
    (干货——以上3个Attention都是干货)

2)看个荔枝:

  • 2.1)如果只想滚动遍历结果集, 而不想编辑它 的数据,那么可以使用以下语句:

    Statement stat = conn.createStatement(ResultSet.Type_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

  • 2.2)现在,通过调用以下方法获得 的所有结果集都将是可滚动的:

    ResultSet rs = stat.executeQuery(query);

  • 2.3) 可滚动的 结果集有一个游标, 用以指示当期位置;

Attention)

  • A1)并不是所有的数据库驱动程序都支持可滚动和可更新的结果集;
  • A2)使用 DatabaseMetadata 接口中的 supportsResultSetType 和 supportsResultSetConcurrency 方法, 我们可以获知在使用特定的驱动程序时, 某个数据库究竟支持哪些结果集类型以及哪些并发模式; (干货——查看某个数据库究竟支持哪些结果集类型以及哪些并发模式)
  • A3)也可以使用 ResultSet 接口中的 getType 和 getConcurrency 方法 查看结果集实际支持的模式;

3)滚动操作: (干货——滚动集的滚动操作)

  • 3.1)向后滚动: rs.previous(); 如果游标位于一个实际的行上,那么该方法将返回true; 如果游标位于第一行之前,那么就返回false;
  • 3.2)将游标向后或向前移动多行: rs.relative(n); n为正数, 向前移动;或负数, 向后移动; n为0, 不移动;
  • 3.3)将游标设置到指定的行号上: rs.absolute(n);
  • 3.4) 调用以下方法将返回当前行的行号: int curRow = rs.getRow();
  • 3.5)结果的第一行是1, 而不是0;如果返回0, 那么当前游标不在任何行上, 它要么位于第一行前,或最后一行之后; (干货——可滚动结果集的第一行的index是1, 而不是0)
  • 3.6)其他操作: first, last, beforeFirst, afterLast 方法 , 与 isFirst , isLast, isBeforeFirst, isAfterLast 方法;

Attention) rs.isAfterLast() 表示当前行游标是在最后一行之后吗。 而 rs.isLast() 表示这是最后一行吗。他们是有差别的。

4)看个荔枝:(只打印奇数行的name)

  • 4.1)for souce code, please visit : (https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/ScrollResultSet.java)
  • 4.2)key source code at a glance:
public static void main(String[] args){try{try(Connection conn = getConnection()){String sql = "select name from student";// TYPE_SCROLL_INSENSITIVE == 结果集可以滚动但对数据库变化不敏感;// CONCUR_READ_ONLY == 且结果集不能用于更新数据库(default);Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);ResultSet rs = stat.executeQuery(sql);int rowno;while(true){rowno = rs.getRow();                    if(rowno < 1){rs.absolute(1); // 将游标设置到指定的行号上}System.out.println("rowno = " + rs.getRow());// attention for rs.getString not changing row cursorSystem.out.println("row[" + rs.getRow() + "] = " + rs.getString(1));if(!rs.isLast()){// 将游标向后或向前移动多行: rs.relative(n); n为正数, 向前移动;或负数, 向后移动; n为0, 不移动;rs.relative(2);}if(rs.isLast()){break;}}stat.close();conn.close();}}catch(Exception e){e.printStackTrace();}
  • 4.3)relative printing results as follows:

【2】可更新的结果集

1)如果希望编辑结果集中的数据,并且将结果集上的数据变更自动反应到数据库中, 那么就必须使用可更新的结果集;可更新的结果集并非必须是可滚动的, 但如果将 数据提供给用户去编辑, 那么通常也会希望结果集时可滚动的;
(干货——可更新的结果集并非必须是可滚动的, 但如果将 数据提供给用户去编辑, 那么通常也会希望结果集时可滚动的;)
(干货——为什么引入可滚动的结果集? 是为了将结果集上的数据变更自动反应到数据库中)
2)如果要获得可更新的结果集,应该使用以下方法创建一条语句:

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

Attention)

  • A1)并非所有的查询都会返回可更新的结果集;
  • A2)如果查询涉及多个表的连接操作, 那么它所产生的结果集将是不可更新的;
  • A3)可以调用 ResultSet 接口中的 getConcurrency 方法来确定结果集是否是可更新的;

3)看个荔枝: 迭代遍历所有图书并更新它们的价格:

String query = "select * from book";
ResultSet rs = stat.executeQuery(query);
while(rs.next)
{if(...){double price = rs.getDouble("price");rs.updateDouble("price", price + 1000);rs.updateRow(); // 干货——以上两行是更新数据库的操作}
}

Attention)

  • A1)在使用第一个参数为列序号的updateXXX 方法时, 请注意这里的列序号指的是该列在结果集中的序号, 而不是数据库的中的列序号;
  • A2)udpateXXX 方法:改变的只是结果集中的行值, 而非数据库 中的值;当更新完字段后,必须调用 updateRow 方法, 这个方法将当前行中的更新信息发送给数据库; (干货——当更新完字段后,必须调用updateRow 方法)
  • A3)cancelRowUpdates方法:取消对当前行的更新;

4)如果想在数据库中添加一行新纪录,按如下步骤进行: (干货——在可更新结果集中添加一行新记录到数据库)

  • step1) 使用 moveToInsertRow 方法: 将游标移动到特定的位置, 我们称之为插入行;
  • step2)调用 udpateXXX 方法 在插入行的位置上创建一个新的行;
  • step3) 调用insertRow 方法:将新建的行发送给 数据库;
  • step4)完成插入后,调用 moveToCurrentRow 方法: 将游标移动会调用  moveToCurrentRow  方法之前的位置;

5)看个实例程序:

rs.moveToInsertRow();
rs.updateString("title", title);
rs.updateString("title1", title1);
rs.updateString("title2", title2);
...
rs.updateDouble("price", price);
rs.insertRow();
rs.moveToCurrentRow();

Attention)

  • A1)你无法控制在结果集或数据库中添加新数据的位置;
  • A2) 对于在插入行中没有指定值的列,将被设置为 null, 而如果这个列有 not null 约束的话, 那么将会抛出异常,而这一行无法插入;
  • A3)你可以使用以下方法删除游标所指的行:
    • A3.1) rs.deleteRow();
    • A3.2)deleteRow 方法: 会立即将该行从结果集和数据库中删除;
    • A3.3)ResultSet 接口中的方法: updateRow, insertRow, deleteRow 方法的执行效果等同于 sql 命令中的update, insert 和 delete 方法;


6)看个荔枝:(将奇数行的name追加_odd, 偶数行的name追加_even)

  • 6.1)for souce code, please visit :
    (https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/UpdatableResultSet.java)
  • 6.2)key source code at a glance:
public static void main(String[] args){try{try(Connection conn = getConnection()){String sql = "select id, name from student";// TYPE_SCROLL_SENSITIVE == 结果集可以滚动且对数据库变化不敏感;// CONCUR_UPDATABLE == 且结果集能够应用于更新数据库;Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);// get 可更新的 结果集ResultSet rs = stat.executeQuery(sql);int rowno;while(true){rowno = rs.getRow();                    if(rowno < 1){rs.absolute(1); // 将游标设置到指定的行号上}if(rs.getRow() % 2 != 0){rs.updateString("name", rs.getString("name") + "_odd");}else{rs.updateString("name", rs.getString("name") + "_even");}rs.updateRow();// attention for rs.getString not changing row cursorSystem.out.println("row[" + rs.getRow() + "] = " + rs.getString(2));// 将游标向后或向前移动多行: rs.relative(n); n为正数, 向前移动;或负数, 向后移动; n为0, 不移动;rs.relative(1);if(rs.isAfterLast()){break;}}stat.close();conn.close();}}catch(Exception e){e.printStackTrace();}
  • 6.3)relative printing results as follows:

java数据库编程——可滚动和可更新的结果集相关推荐

  1. java数据库编程——事务

    [0]README 1) 本文部分文字描述转自 core java volume 2 , 测试源代码均为原创, 旨在理解 java数据库编程--事务 的基础知识 : 2)for database co ...

  2. java数据库编程——执行查询操作(二)

    [0]README 1) 本文部分文字描述和source code 均转自 core java volume 2 , 旨在理解 java数据库编程--执行查询操作(二) 的基础知识 : 2) 本文和 ...

  3. java数据库编程——执行查询操作(一)

    [0]README 1) 本文部分文字描述和source code 均转自 core java volume 2 , 旨在理解 java数据库编程--执行查询操作 的基础知识 : 2) 本文和 jav ...

  4. java数据库编程——执行SQL 语句

    [0]README 1) 本文文字描述+source code 均转自 core java volume 2 , 旨在理解 java数据库编程--执行SQL 语句 的基础知识 : 2)for sour ...

  5. java基础类库——java数据库编程,JDBC连接(原生数据库连接)(十)

    java数据库编程,JDBC连接(原生数据库连接) JDBC严格来讲不属于一门技术,它属于一种服务.所有的操作流程都是固定的.JDBC是java提供的数据库操作的一个标准(它就是一组相关的标准接口), ...

  6. java数据库编程(二) 数据库操作

    关于数据库的连接方法已在java 数据库编程(一)JDBC连接Sql Server数据库一文中为大家介绍,还没有链接数据库的小伙伴请先点击查看. 今天首先为大家介绍一下数据库的连接及操作的核心类与接口 ...

  7. java数据库编程——元数据(metadata)+web 与企业应用中的连接管理

    [0]README 1) 本文部分文字描述转自 core java volume 2 , 测试源代码均为原创, 旨在理解 java数据库编程--元数据(metadata)+web 与企业应用中的连接管 ...

  8. java数据库编程中查询结果的表格式输出_Java数据库编程中查询结果的表格式输出...

    派性劳拉德高顺价老僧水牌电烫,湟中胜利财大不恤名花抹胸,果儿四坝风冈普基挡车关掉临池,脑死愀然草荐木笼电能.公话理念湮没不讳公使难看! 摄氏欠安宣和拉道开封关掉明洁名贵.不名滑膜俊美盲女长虹火主乐律超 ...

  9. Java 数据库编程 ResultSet 的 使用方法

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

最新文章

  1. 【Python】序列解包 and * 和 ** 的区别
  2. javaScript原生定义的函数
  3. 浅析微软的网关项目 -- ReverseProxy
  4. 信号与系统实验:信号抽样
  5. C#中的泛型化方法的实现
  6. 阿里与腾讯“智慧城市”的O2O谁更强?(分享)
  7. python用for循环求平均分_Python中for循环的一些非常规操作
  8. 慕课网仿去哪儿项目笔记--(一)-初始化准备
  9. 谷歌浏览器获取网页元素的xpath
  10. python表示倍数_python 求倍数
  11. 修改数据库长度mysql_mysql 修改数据库长度
  12. 使用物理学和领域知识的神经网络的无标签监督解读(上)
  13. linux网络设备驱动(一)
  14. windows 10 安装 jdk15 教程
  15. 冷喷涂服务行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  16. 做开发的你需要了解:Serverless 可观测性的过去、现在与未来
  17. 达内培训python 好不好
  18. 数据中台推不动?手把手教你落地搭建!
  19. 算法学习之路|幼儿园买玩具
  20. SuperMap iClient for OpenLayers图层组控制实现方法

热门文章

  1. Find 3-friendly Integers
  2. [八省联考2018]劈配 (匈牙利)
  3. CF605E-Intergalaxy Trips【期望dp】
  4. P7077-函数调用【拓扑排序,dp】
  5. USACO2.4のP1522-牛的旅行(Cow Tours)【最短路Flody】
  6. P1282-多米诺骨牌【dp,背包】
  7. 【2018.5.12】模拟赛之三-ssl2415 连通块【并查集】
  8. 牛客练习赛 58——树链剖分
  9. 【期望】路径长度(金牌导航 期望-1)
  10. BZOJ5358: [Lydsy1805月赛]口算训练