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

【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:
    这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331436.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring入门(四)之BeanFactory

一、BeanFacotry访问一个Spring bean容器的根接口。这是一个Bean容器基本客户端视图&#xff1b;进一步的接口如ListableBeanFactory和configurablebeanfactory供特定用途。此接口由包含许多bean定义的对象来实现&#xff0c;每个对象都有唯一的字符串名称标识。根据bean定义&a…

apache derby_Apache Derby数据库JVM安全策略

apache derby抽象 我已经发布了许多有关Derby的博客&#xff1a; Derby数据库备份 同一主机上的多个Derby网络服务器 Apache Derby数据库用户和权限 与Maven和内存中Derby数据库的集成测试 这本不打算是一个系列。 但是多年来&#xff0c;我越来越多地使用Derby。 我开始将…

java数据库编程——事务

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java数据库编程——事务 的基础知识 &#xff1b; 2&#xff09;for database connection config, please visit &#xff1a; https://github.co…

算法九之基数排序

一、基数排序 &#xff08;1&#xff09;基数排序的简介 基数排序不同于其他的排序算法&#xff0c;它不是基于比较的算法。基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。它是一种稳定的排序算法。  通常用于对数的排序选择的是最低位优先法&#xff…

在Spring中使用多个动态缓存

在第三篇有关Spring&#xff08;长时间&#xff09;的缓存管理器的文章中&#xff0c;我想通过展示如何配置多个动态创建缓存的缓存管理器来扩展前 两个 。 Spring具有CompositeCacheManager &#xff0c;从理论上讲&#xff0c;它应该允许使用多个缓存管理器。 它通过询问基础…

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

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java数据库编程——元数据&#xff08;metadata&#xff09;web 与企业应用中的连接管理 的基础知识 &#xff1b; 2&#xff09;for database co…

托管 非托管_如何在托管的Kubernetes上备份Neo4J

托管 非托管在下面的视频中&#xff0c;我将解释如何对在托管Kubernetes环境中运行的Neo4J实例进行完整和增量备份。 我们将使用其他Pod进行远程备份&#xff0c;并将备份数据存储在托管环境提供的持久卷上。 如果您想知道如何将Neo4J部署到托管Kubernetes&#xff0c;请查看以…

java国际化——Locale+数字格式

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——Locale数字格式 的基础知识 &#xff1b; 2&#xff09; java 编程语言是第一个设计成为全面支持国际化的语言。 2.1&#xff09;…

Linux指令类型(一)change指令

一、change指令 chattr chgrp chmod chown chfn chsh chroot 二、ch指令详细介绍 &#xff08;1&#xff09;chattr 全名&#xff1a;change attribute 作用&#xff1a;chattr命令用于改变文件属性 语法&#xff1a;chattr [-RV][-v<版本编号>]…

restful rest_HATEOAS的RESTful服务。 REST:刷新器

restful rest在这篇文章中&#xff0c;我们将介绍有关HATEOAS的RESTful服务的综合文章。 REST&#xff1a;刷新器。 1.简介 “不好了&#xff01; 请&#xff0c;不要再发表有关REST的文章&#xff01;” 你们中的许多人可能会尖叫&#xff0c;这是正确的。 已经出版了太多的…

Unicode® Character Name Index

【0】README 0.1&#xff09; there are unicodes for varients of alphabet a, for that of b, c, or d and so on, please visit http://unicode.org/charts/charindex.html [A] A WITH ACUTE, LATIN CAPITAL LETTER 00C1 A WITH ACUTE, LATIN SMALL LETTER 00E1 A WITH…

java8 hash算法

一、hash算法哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值&#xff0c;这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母&#xff0c;随后的哈希都将产生不同的值。要找到散列为同…

exchanger_如何通过示例在Java中使用Exchanger

exchanger大家好&#xff0c;如果您在并发Java应用程序中工作&#xff0c;那么您可能听说过java.util.concurrent包的Exchanger类。 Java中的Exchanger是Java 1.5中与CountDownLatch &#xff0c; CyclicBarrier和Semaphores一起引入的另一个并发或同步实用程序。 顾名思义&…

Java Enumeration接口与Iterator接口

一、Enumeration接口 Enumeration接口中定义了一些方法&#xff0c;通过这些方法可以枚举&#xff08;一次获得一个&#xff09;对象集合中的元素。 这种传统接口已被迭代器取代&#xff0c;虽然Enumeration 还未被遗弃&#xff0c;但在现在代码中已经被很少使用了。尽管如此&a…

java国际化——日期和时间+排序

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——日期和时间排序 的基础知识 &#xff1b; 【1】日期和时间 1&#xff09;当格式化日期和时间时&#xff0c;需要考虑4个与 Locale …

jvm 垃圾收集算法_JVM垃圾收集和优化

jvm 垃圾收集算法总览 在对系统进行性能相关问题的故障排除时&#xff0c;内存优化是一个需要深入分析每个系统在内存中存储的内容&#xff0c;存储时间和访问方式的场所。 这篇文章是要对背景信息进行注释&#xff0c;并在此工作中要注意一些要点&#xff0c;这些工作要针对基…

数据库SQL索引

一、索引的意义 表中创建索引&#xff0c;以便更加快速高效地查询数据。 用户无法看到索引&#xff0c;它们只能被用来加速搜索/查询。 注释&#xff1a;更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间&#xff0c;这是由于索引本身也需要更新。因此&#x…

java国际化——消息格式化+文本文件和字符集

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——消息格式化文本文件和字符集 的基础知识 &#xff1b; 2&#xff09; 由于本文涉及到的源代码都比较简单&#xff0c;所以直接将全…

java 8 新功能详解_Java 8和Java 14之间的新功能

java 8 新功能详解从版本9开始&#xff0c;Java每6个月就有一次新功能&#xff0c;因此很难跟踪这些新更改。 互联网上的大多数信息都描述了最近2个Java版本之间的变化。 但是&#xff0c;如果您的情况与我相似&#xff0c;则说明您使用的不是Java的最新版本&#xff0c;而是使…

Tomcat配置虚拟内存

一、Tomcat启动参数JAVA_OPTS参数说明   -server 启用jdk 的 server 版&#xff1b;   -Xms java 虚拟机初始化时的堆最小内存&#xff1b;   -Xmx java 虚拟机可使用堆的最大内存&#xff1b;   -XX: PermSize 非堆内存永久保留区域   -XX:MaxPermS…