JDBC1.0 、JDBC2.0 、JDBC3.0 中分别用以下方法创建Statement 。

JDBC1.0 : createStatement()

JDBC2.0 : createStatement(resultSetType, resultSetConcurrency)

JDBC3.0 : createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)

下面依次分析resultSetType 、resultSetConcurrency 、resultSetHoldability 这几个参数的含义。

一 ResultSetType

resultSetType 的可选值有: ResultSet.TYPE_FORWARD_ONLY 、ResultSet.TYPE_SCROLL_INSENSITIVE、ResultSet.TYPE_SCROLL_SENSITIVE 。

1 :ResultSet.TYPE_FORWARD_ONLY

默认的cursor 类型,仅仅支持结果集forward ,不支持backforward ,random ,last ,first 等操作。

2 :ResultSet.TYPE_SCROLL_INSENSITIVE

支持结果集backforward ,random ,last ,first 等操作,对其它session 对数据库中数据做出的更改是不敏感的。

实现方法:从数据库取出数据后,会把全部数据缓存到cache 中,对结果集的后续操作,是操作的cache 中的数据,数据库中记录发生变化后,不影响cache 中的数据,所以ResultSet 对结果集中的数据是INSENSITIVE 的。

3 :ResultSet.TYPE_SCROLL_SENSITIVE

支持结果集backforward ,random ,last ,first 等操作,对其它session 对数据库中数据做出的更改是敏感的,即其他session 修改了数据库中的数据,会反应到本结果集中。

实现方法:从数据库取出数据后,不是把全部数据缓存到cache 中,而是把每条数据的rowid 缓存到cache 中,对结果集后续操作时,是根据rowid 再去数据库中取数据。所以数据库中记录发生变化后,通过ResultSet 取出的记录是最新的,即ResultSet 是SENSITIVE 的。 但insert 和delete 操作不会影响到ResultSet ,因为insert 数据的rowid 不在ResultSet 取出的rowid 中,所以insert 的数据对ResultSet 是不可见的,而delete 数据的rowid 依旧在ResultSet 中,所以ResultSet 仍可以取出被删除的记录( 因为一般数据库的删除是标记删除,不是真正在数据库文件中删除 )。

做个试验,验证一下SENSITIVE 特性。数据库为oracle10g ,驱动为ojdbc14.jar 。

test 表中数据如下:

c1 c2 c3
1c1 1c2 1c3
2c1 2c2 2c3
3c1 3c2 3c3

程序如下:

Java代码  
  1. public static void testResultSetSensitive(Connection conn) throws Exception{
  2. String sql = "SELECT c1,c2,c3 FROM test";
  3. try {
  4. Statement stmt = conn
  5. .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
  6. ResultSet rs = stmt.executeQuery(sql);
  7. while (rs.next()) {
  8. System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2)
  9. + "\t" + rs.getString(3));
  10. Thread.sleep(20000);
  11. }
  12. rs.close();
  13. stmt.close();
  14. } catch (SQLException e) {
  15. e.printStackTrace();
  16. } finally {
  17. try {
  18. conn.close();
  19. } catch (Exception e) {
  20. }
  21. }
  22. }

定义ResultSet 为 ResultSet. TYPE_SCROLL_SENSITIVE 类型,首先执行 sql 访问数据库,然后执行 rs.next() 移动游标取数据。在循环里面加上 Thread.sleep (20000) 的目的是为了我们有时间在后台把数据库里的数据改了。比如当在循环里打印出第一行的数据后,我们在后台,把第三行数据的 c3 列改成 ”3uuu” 。如果 ResultSet 真的是敏感的话,那应该取出 ”3uuu” ,而不是原始的“ 3c 3 ”。但最终的结果却是如下:

[ 行号: 1] 1c1   1c2   1c3

[ 行号: 2] 2c1   2c2   2c3

[ 行号: 3] 3c1   3c2   3c3

数据没变呀,ResultSet 不敏感啊!于是去查阅资料,找了n 久,还是在英文文档上找到了答案。原来是fetchsize 的问题。调用ResultSet 的next 方法取数据时,并不是每调用一次方法就去数据库里查一次,而是有个fetchSize, 一次取fetchSize 条数据。Oracle 默认的fetchsize 等于10 ,所以上面的代码在第一次调用rs.next() 时,就已经把3 条数据都取出来了,所以才会有上面的结果。

第二次实验,在ResultSet rs = stmt.executeQuery(sql); 前面加上 stmt.setFetchSize(1); 将fetchSize 设置为1 。然后重新第一次实验的步骤,发现最 终结果为:

[ 行号: 1] 1c1   1c2   1c3

[ 行号: 2] 2c1   2c2   2c3

[ 行号: 3] 3c1   3c2   3uuu

原因就是 fetchsize 设置为 1 时,每次 next 取数时都会重新用 rowid 取数据库里取数据,当然取到的是最新的数据了。

 二 ResultSetConcurrency

ResultSetConcurrency的可选值有2个:       ResultSet.CONCUR_READ_ONLY 在ResultSet中的数据记录是只读的,不可以修改       ResultSet.CONCUR_UPDATABLE 在ResultSet中的数据记录可以任意修改,然后更新到数据库,可以插入,删除,修改。

 三 ResultSetHoldability

ResultSetHoldability 的可选值有2 个 :

HOLD_CURSORS_OVER_COMMIT: 在事务commit 或rollback 后,ResultSet 仍然可用。       CLOSE_CURSORS_AT_COMMIT: 在事务commit 或rollback 后,ResultSet 被关闭。

需要注意的地方:

1 :Oracle 只支持HOLD_CURSORS_OVER_COMMIT 。

2 :当Statement 执行下一个查询,生成第二个ResultSet 时,第一个ResultSet 会被关闭,这和是否支持支持HOLD_CURSORS_OVER_COMMIT 无关。

     四 验证数据库是否支持ResultSet的各种特性

不同的数据库版本及 JDBC 驱动版本,对 ResultSet 的各种高级特性的支持是不一样的,我们可以通过以下方法,来验证具体的数据库及 JDBC 驱动,是否支持 ResultSet 的各种特性。

DatabaseMetaData dbMeta = conn.getMetaData();

然后调用 DatabaseMetaData 对象的以下方法:

boolean supportsResultSetType(int resultSetType);

boolean supportsResultSetConcurrency(int type, int concurrency);

boolean supportsResultSetHoldability(int holdability);

参考的2 篇英文文档:

http://cs.felk.cvut.cz/10gr2/java.102/b14355/jdbcvers.htm (JDBC Standards Support )

http://download.oracle.com/docs/cd/B10501_01/java.920/a96654/resltset.htm#1023642 (Oracle9i JDBC Developer's Guide and Reference Release 2 (9.2))

JDBC ResultSet分析的更多相关文章

  1. JDBC性能分析与优化

    JDBC性能分析与优化V1.0http://www.docin.com/p-758600080.html

  2. java jdbc ResultSet结果通过java反射赋值给java对象

    在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了. ...

  3. 由DB2分页想到的,关于JDBC ResultSet 处理大数据量

    最近在处理DB2 ,查询中,发现如下问题.如果一个查询 count(*),有几十万行,分页如何实现 select row_number() over (order by fid desc ) as r ...

  4. JAVA JDBC 元数据分析小结

    纯干货: 获取数据库名称: /** * 获取数据库的名称 */ public void getDataBaseName() throws Exception { Connection con = DS ...

  5. 将JDBC ResultSet结果集变成List

    private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>() ...

  6. 将JDBC ResultSet结果集转成List

    private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>() ...

  7. MyBatis+Hibernate+JDBC对比分析

    MyBatis目前作为持久层,用的最多,因为它符合互联网开发的变动性,实际开发中需求总会有这样的,那样的变动,MyBatis虽然没有Hibernate那么全自动化,而且对于开发人员的sql能力要求比较 ...

  8. 由于使用JDBC ResultSet的滚动功能而导致的内存溢出

    前天一去公司,老大说,服务器全挂了! 最后排查了半天,结论是内存溢出! 在WAS的DUMP日志中,看得我头晕眼花,终于找到了罪魁祸首,原来是有同事写代码的时候使用了可滚动的结果集导致内存溢出. 什么是 ...

  9. JDBC全部分析

    2.1.搭建实验环境 1.在mysql中创建一个库,并创建user表和插入表的数据. SQL脚本如下: 1 create database jdbcStudy character set utf8 c ...

随机推荐

  1. BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4956(它放在题库后面的格式有一点点问题啦,所以就把它粘下来,方便读者观看) 题目意思:给出一个范围 [ ...

  2. hdu 2112 HDU Today 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目意思:又是求最短路的,不过结合埋字符串来考查. 受之前1004 Let the Balloo ...

  3. 【POJ 1061】 青蛙的约会

    [题目链接] 点击打开链接 [算法] 列出同余方程,然后用exgcd求解 [代码] #include <algorithm> #include <bitset> #includ ...

  4. bzoj3270博物馆——期望概率DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3270 设计一个状态表示两个人分别在两个点的状态,带个标号num[i][j]: 据此得到状态之 ...

  5. 中文环境下PostgreSQL的使用

    虽然官方文档有提到编码的问题,但是对于中文讲的比较简单,给中文的PostgreSQL用户带来很多困扰,本文简单简述一下中文环境下PostgreSQL如何正确设置编码. 一.服务器端的编码设置 Post ...

  6. vue 使用font-awesome 只需两步

    npm 安装font-awesome 以及需要的所有依赖 cnpm install less less-loader css-loader style-loader file-loader font- ...

  7. k8s-资源指标API及自定义指标API-二十三

    一. 原先版本是用heapster来收集资源指标才能看,但是现在heapster要废弃了. 从k8s v1.8开始后,引入了新的功能,即把资源指标引入api: 在使用heapster时,获取资源指标是 ...

  8. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 21. Model 验证 Again

    深入的将Model验证 手动添加验证的错误 view里面显示每个属性的验证错误信息 显示整个model级别错误 自定义验证 如果业务逻辑需要比较复杂的验证.而且这个验证逻辑可能到处复用的话就应该考虑使 ...

  9. bzoj 4871: [Shoi2017]摧毁“树状图”【树形dp】

    做不来--参考https://www.cnblogs.com/ezyzy/p/6784872.html #include<iostream> #include<cstdio> ...

  10. bzoj 4753: [Jsoi2016]最佳团体【01分数规划+二分+树上背包】

    01分数规划,二分答案然后把判别式变成Σp[i]-Σs[i]*mid>=0,然后树上背包判断,设f[i][j]为在i点子树里选j个的最大收益,随便背包一下就好 最丧病的是神卡常--转移的时候要另 ...