JDBC 入门 - 结果集
2015-11-01 18:06
344 查看
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
相关文章推荐
- MVC,如何在视图中申明方法,调用方法?
- POJ-2376 Cleaning Shifts
- 造简单的图片加载框架——ImageLoader的实现
- 12个用得着的JQuery代码片段
- tgz解压
- 第9周—项目4(2)广义表的原子统计
- HDOJ-2578-Dating with girls(1) 【排序 去重 二分】
- filter和interceptor的区别
- 程序中的@Override是什么意思?
- spring mvc常用的注解
- oracle中的分支与循环语句
- お手紙のこと。
- UVa 10114 - Loansome Car Buyer
- [leetcode 26]Remove Duplicates from Sorted Array
- JDK所有版本下载链接
- 跨域rest-service创建与访问解决方案
- request.setCharacterEncoding("UTF-8");
- HDOJ1728(限制转弯的迷宫问题)
- CSS3之2D变形
- Fragment介绍: