JDBC 入门 - 结果集

ResultSet (结果集)

RSType 和 RSConcurrency

当对数据库进行查询操作的时候, 数据库返回的数据通过 ResultSet 接口获取. ResultSet 内部管理了一个 cursor(游标), cursor 指向当前要读的数据, ResultSet 提供了以下三类接口:

  • 游标移动接口, 用来操作移动游标.
  • 获取数据接口, 用来从当前游标指向位置的数据
  • 更新数据接口, 用来更新当前游标指向位置的数据, 并可以更改对应数据库中的数据.

ResultSet 的类型:

在创建 Statement 的时候, 可以添加两个参数.

  • createStatement(int RSType, int RSConcurrency);
  • prepareStatement(String SQL, int RSType, int RSConcurrency);
  • prepareCall(String sql, int RSType, int RSConcurrency);

其中第一个参数RSType主要描述两件事:

  • Cusor 是否可以前后移动
  • 已经取出的结果集对数据库的改动是否需要更新

RSType 的值可以取下面三个:

  • ResultSet.TYPE_FORWARD_ONLY: Cursor 只能往前移动, 默认值
  • ResultSet.TYPE_SCROLL_INSENSITIVE: Cursor 可以前后移动, 但是对于数据库的改动不关心.
  • ResultSet.TYPE_SCROLL_SENSITIVE: Cursor 可以前后移动, 并且当数据库发生改动的时候, ResultSet也会随之更新.

RSConcurrency 用来描述我们是否可以更新结果集中的数据到数据库. 有两个值可以用:

  • ResultSet.CONCUR_READ_ONLY: 结果集是只读的
  • ResultSet.CONCUR_UPDATABLE: 结果集是可以更新的.

注意, 并不是所有的数据库都支持这些类型, 可以查看数据库驱动的支持情况:

    public static void printResultSetSupport(Connection conn) {
        DatabaseMetaData md = null;
        try {
            md = conn.getMetaData();
            // Verify ResultSet‘s type
            System.out.println("Supports TYPE_FORWARD_ONLY: " + md.supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY));
            System.out.println("Supports TYPE_SCROLL_INSENSITIVE: " + md.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE));
            System.out.println("Supports TYPE_SCROLL_SENSITIVE: " + md.supportsResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE));
            // Verify ResultSet‘s concurrency
            System.out.println("Supports CONCUR_READ_ONLY for TYPE_FORWARD_ONLY: " + md.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY));
            System.out.println("Supports CONCUR_UPDATABLE for TYPE_FORWARD_ONLY: " + md.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE));

            System.out.println("Supports CONCUR_READ_ONLY for TYPE_SCROLL_INSENSITIVE: " + md.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY));
            System.out.println("Supports CONCUR_UPDATABLE for TYPE_SCROLL_INSENSITIVE: " + md.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE));

            System.out.println("Supports CONCUR_READ_ONLY for TYPE_SCROLL_SENSITIVE: " + md.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY));
            System.out.println("Supports CONCUR_UPDATABLE for TYPE_SCROLL_SENSITIVE: " + md.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE));
        } catch(SQLException e) {
            printSQLException(e);
        }
    }

MySQL 的执行结果如下:

Supports TYPE_FORWARD_ONLY: false
Supports TYPE_SCROLL_INSENSITIVE: true
Supports TYPE_SCROLL_SENSITIVE: false
Supports CONCUR_READ_ONLY for TYPE_FORWARD_ONLY: true
Supports CONCUR_UPDATABLE for TYPE_FORWARD_ONLY: true
Supports CONCUR_READ_ONLY for TYPE_SCROLL_INSENSITIVE: true
Supports CONCUR_UPDATABLE for TYPE_SCROLL_INSENSITIVE: true
Supports CONCUR_READ_ONLY for TYPE_SCROLL_SENSITIVE: false
Supports CONCUR_UPDATABLE for TYPE_SCROLL_SENSITIVE: false

__ 我在测是的时候, 发现 MySQL 默认的 Cursor 竟然也可以往前往后移动! 难道 MySQL 默认的是 TYPE_SCROLL_INSENSITIVE?

其实, 不是的, MYSQL 会缓存结果集, 导致默认类型的 TYPE_FORWARD_ONLY 升级成了可以前后移动的. 只要我们调整一下将结果集的缓存设为最小, cursor 的行为就正常了:

tatement s = dbConnection.createStatement(
        ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);

更多解释请看此链接 __

JavaDB 的执行结果如下:

Supports TYPE_FORWARD_ONLY: true
Supports TYPE_SCROLL_INSENSITIVE: true
Supports TYPE_SCROLL_SENSITIVE: false
Supports CONCUR_READ_ONLY for TYPE_FORWARD_ONLY: true
Supports CONCUR_UPDATABLE for TYPE_FORWARD_ONLY: true
Supports CONCUR_READ_ONLY for TYPE_SCROLL_INSENSITIVE: true
Supports CONCUR_UPDATABLE for TYPE_SCROLL_INSENSITIVE: true
Supports CONCUR_READ_ONLY for TYPE_SCROLL_SENSITIVE: false
Supports CONCUR_UPDATABLE for TYPE_SCROLL_SENSITIVE: false

Cursor Holdability

关于 Cursor 其实还有一个属性, 是关于事务提交后, 是否需要关闭结果集的问题. 相关 API 为:

conn.setHoldability();

来改变这种行为, 可以传入的参数有:

  • HOLD_CURSORS_OVER_COMMIT: 当调用 Connection.commit()后, ResultSet 将不会关闭, 一般用于只读的结果集中.
  • CLOSE_CURSORS_AT_COMMIT : 当调用 Connection.commit()后, ResultSet 将会关闭.

JDBC 没有规定默认的值, 但是有相应的 API 来获取默认值以及支持情况:

    public static void printCursorHoldability(Connection conn) throws SQLException {
        DatabaseMetaData md = conn.getMetaData();
        System.out.println("-- ResultSet Cursor Holdability --");
        int holdability = md.getResultSetHoldability();
        if (holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT) {
            System.out.println("Default: CLOSE_CURSORS_AT_COMMIT");
        } else if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) {
            System.out.println("Default: ResultSet.HOLD_CURSORS_OVER_COMMIT");
        }
        System.out.println("Supports CLOSE_CURSORS_AT_COMMIT: "
                + md.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT));
        System.out.println("Supports HOLD_CURSORS_OVER_COMMIT: "
                + md.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
    }

MySQL 结果是:

-- ResultSet Cursor Holdability --
Default: ResultSet.HOLD_CURSORS_OVER_COMMIT
Supports CLOSE_CURSORS_AT_COMMIT: false
Supports HOLD_CURSORS_OVER_COMMIT: true

而 JavaDB 的结果是:

-- ResultSet Cursor Holdability --
Default: ResultSet.HOLD_CURSORS_OVER_COMMIT
Supports CLOSE_CURSORS_AT_COMMIT: true
Supports HOLD_CURSORS_OVER_COMMIT: true
时间: 2024-10-20 07:22:33

JDBC 入门 - 结果集的相关文章

01.JDBC入门

一.JDBC入门 1.JDBC简介 JDBC, 即Java Database Connectivity,JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序.即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库,比如建立数据库连接.执行SQL语句进行数据的存取操作. JDBC规范采用接口和实现分离的思想设计了Java数据库编程的框架.接口包含在java.sql及j

web day17 JDBC入门,DAO模式mySQL时间类型转换,批处理

JDBC入门 1.JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库. 2.JDBC原理 最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现.SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动! 3.JDBC核心类(接口)介绍 JDBC中

day17(JDBC入门&jdbcUtils工具介绍)

day17 JDBC整体思维导图 JDBC入门 导jar包:驱动! 加载驱动类:Class.forName("类名"); 给出url.username.password,其中url背下来! 使用DriverManager类来得到Connection对象! ? ? ? 1 什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java

Java进阶学习第十七天——JDBC入门学习

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.05.11 lutianfei none JDBC JDBC介绍 JDBC是什么? JDBC(Java Data Base Connectivity,java数据库连接) SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. 简单说,就是可以直接通过java语言去操作数据库. jdbc是一套标准,它是由一些接口与类组成的. 组成JDBC的类和接口 java.sql 类:Drive

21、jdbc入门1

jdbc入门 什么是jdbc 使用java代码(程序)发送sql语句的技术,就是jdbc技术!!!! 连接案例 /** * jdbc连接数据库 * @author APPle * */ public class Demo1 { //连接数据库的URL private String url = "jdbc:mysql://localhost:3306/day17"; // jdbc协议:数据库子协议:主机:端口/连接的数据库 // private String user = "

Spring JDBC入门

Spring将替我们完成所有使用JDBC API进行开发的单调乏味的.底层细节处理工作. 操作JDBC时Spring可以帮我们做这些事情: 定义数据库连接参数,打开数据库连接,处理异常,关闭数据库连接 我们仅需要关注: 声明SQL语句,处理每一次得到的结果 一个较为简单的例子与讲解 JdbcTemplate类 JdbcTemplate是core包的核心类.它替我们完成了资源的创建以及释放工作,从而简化了我们对JDBC的使用.它还可以帮助我们避免一些常见的错误,比如忘记关闭数据库连接.JdbcTe

【原创 Hadoop&Spark 动手实践 5】Spark 基础入门,集群搭建以及Spark Shell

Spark 基础入门,集群搭建以及Spark Shell 主要借助Spark基础的PPT,再加上实际的动手操作来加强概念的理解和实践. Spark 安装部署 理论已经了解的差不多了,接下来是实际动手实验: 练习1 利用Spark Shell(本机模式) 完成WordCount spark-shell 进行Spark-shell本机模式 第一步:通过文件方式导入数据 scala> val rdd1 = sc.textFile("file:///tmp/wordcount.txt")

com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行

参考博客com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行 java获取结果集,if(rs!=null),和while(rs.next())区别  com.microsoft.sqlserver.jdbc.SQLServerException: 结果集没有当前行. st = conn.createStatement(); ResultSet rs = st.executeQuery(sql); if(rs!=null) {//rs.

JDBC 入门 - 建立连接

JDBC 入门 - 建立连接 建立连接 在于数据库交互的时候, 第一件事是和数据源(Data Source)也就是数据库建立连接(Connection). 可以从这两个类从数据源取得连接: DriverManager: 在 java.sql 包中, 连接时必须要指定 URL 去连接, 在 JDBC4.0 之前都要显式地去加载驱动类, JDBC4.0后自动加载 CLASSPATH 中的驱动. DataSource: 在 javax.sql 包中, 与 Driver Manager 不同的是, 一个