`

JDBC ResultSet分析

阅读更多

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

JDBC1.0 createStatement()

JDBC2.0 createStatement(resultSetType, resultSetConcurrency)

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

 

下面依次分析resultSetTyperesultSetConcurrencyresultSetHoldability 这几个参数的含义。

 

一 ResultSetType

 

      resultSetType 的可选值有: ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVEResultSet.TYPE_SCROLL_SENSITIVE

 

1 ResultSet.TYPE_FORWARD_ONLY

默认的cursor 类型,仅仅支持结果集forward ,不支持backforwardrandomlastfirst 等操作。  

 

2 ResultSet.TYPE_SCROLL_INSENSITIVE

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

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

 

3 ResultSet.TYPE_SCROLL_SENSITIVE

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

 

实现方法:从数据库取出数据后,不是把全部数据缓存到cache 中,而是把每条数据的rowid 缓存到cache 中,对结果集后续操作时,是根据rowid 再去数据库中取数据。所以数据库中记录发生变化后,通过ResultSet 取出的记录是最新的,即ResultSetSENSITIVE 的。insertdelete 操作不会影响到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.   
  3.         String sql = "SELECT c1,c2,c3 FROM test";   
  4.         try {   
  5.             Statement stmt = conn   
  6.                     .createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);   
  7.                
  8.             ResultSet rs = stmt.executeQuery(sql);   
  9.                
  10.             while (rs.next()) {   
  11.                 System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2)   
  12.                         + "\t" + rs.getString(3));   
  13.                 Thread.sleep(20000);   
  14.             }   
  15.                
  16.             rs.close();   
  17.             stmt.close();   
  18.         } catch (SQLException e) {   
  19.             e.printStackTrace();   
  20.         } finally {   
  21.             try {   
  22.                 conn.close();   
  23.             } catch (Exception e) {   
  24.             }   
  25.         }   
  26.     }  
public static void testResultSetSensitive(Connection conn) throws Exception{

		String sql = "SELECT c1,c2,c3 FROM test";
		try {
			Statement stmt = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			ResultSet rs = stmt.executeQuery(sql);
			
			while (rs.next()) {
				System.out.println("[行号:" + rs.getRow() + "]\t" + rs.getString(1) + "\t" + rs.getString(2)
						+ "\t" + rs.getString(3));
				Thread.sleep(20000);
			}
			
			rs.close();
			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (Exception e) {
			}
		}
	}

 

定义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 的问题。调用ResultSetnext 方法取数据时,并不是每调用一次方法就去数据库里查一次,而是有个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: 在事务commitrollback 后,ResultSet 仍然可用。
     CLOSE_CURSORS_AT_COMMIT:
在事务commitrollback 后,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连接数据库步骤深刻分析

    创建一个以JDBC连接数据库的程序,包含7个步骤: 1、加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)...

    jdbc-demo:二进制详解系列(二)------ jdbc-mysql的使用和分析-mysql

    通过提供DriverManager , Connection , Statement , ResultSet等接口将开发人员与数据库提供商隔离,开发人员只需要面对JDBC接口,无需担心如何跟数据库交互。几个重要的类类名作用DriverManager驱动管理器,用于...

    计算机程序设计(Java)-教案--单元十--数据库编程技术.docx.docx

    教学方法 :・问题导引法:通过给学生提出实际编程中出现的问题来引入教学内容,使学生在主动分析、讨论和解决问题的过程中掌握所学知 计算机程序设计(Java)-教案--单元十--数据库编程技术全文共11页,当前为第2页...

    Java连接数据库的综合类

    在使用Dbutils 之前,我们Dao层使用的技术是JDBC,那么分析一下JDBC的弊端: ①数据库链接对象、sql语句操作对象,封装结果集对象,这三个对象会重复定义 ②封装数据的代码重复,而且操作复杂,代码量大 ③释放资源...

    大数据运维技术第9章 Sqoop组件安装配置.pptx

    Sqoop相关知识; 多数使用Hadoop技术处理大数据业务的企业,有大量的数据存储在关系型数据中。由于没有工具支持,Hadoop和关系型数据库之间的数据传输是很困难的事情。... JDBC的ResultSet接口提供了

    Java数据编程指南

    Java数据库连接(JDBC) 什么是JDBC JDBC结构 开始起步 使用JDBC 一个简单的范例 对映Java与SQL类型 处理SQL错误 ResultSet与数据库元数据 JDBC中的事务处理 一个JDBC事务范例 ...

    网络及数据库编程设计.doc

    " "import java.sql.ResultSet; " "import java.sql.Statement; " " " "/** " "* 数据库连接和关闭工具类 " "* @author ruochen " "* @version 1.0 " "*/ " "public class DBConfig { " "/** 定义数据库驱动类名称 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    12.1.3 仔细分析recordTransport()方法 338 12.2 初用接口 339 12.2.1 准备好需要用到的类 339 12.2.2 认识接口的代码组成 340 12.2.3 什么是接口 341 12.2.4 使用接口仅需一步——实现接口 342 12.2.5 接口...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    12.1.3 仔细分析recordTransport()方法 338 12.2 初用接口 339 12.2.1 准备好需要用到的类 339 12.2.2 认识接口的代码组成 340 12.2.3 什么是接口 341 12.2.4 使用接口仅需一步——实现接口 342 12.2.5 接口...

    JSP动态网站开发基础教程与实验指导(从基础到应用)光盘

    6.2.5 查询结果类:ResultSet 133 6.3 JDBC数据库操作实例 136 6.3.1 新建数据库元素 137 6.3.2 插入数据 138 6.3.3 显示数据 140 6.3.4 更新及删除数据 142 6.3.5 数据库分页显示 143 6.3.6 连接Access数据库 145 ...

    java基础案例与开发详解案例源码全

    18.2.4 ResultSet接口467 18.3 JDBC操作SQL469 18.4 JDBC基本示例473 18.5 JDBC应用示例479 18.6 本章习题492 第19章 19.1 网络编程的基本概念494 19.1.1 网络基础知识494 19.1.2 网络基本概念495 19.1.3 网络传输...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    7.4.5 结果集ResultSet接1:2 7.5 JDBC操作数据库 7.5.1 向数据库中插入数据 7.5.2 从数据库中查询所需数据 75.3 修改数据库中的数据 7.5.4 删除无用的数据 7.5.5 批处理数据操作 7.5.6 应用存储过程进行数据操作 ...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。  《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 ...

    Java开发详解.zip

    031706_【第17章:Java数据库编程】_ResultSet接口笔记.pdf 031707_【第17章:Java数据库编程】_PreparedStatement接口笔记.pdf 031708_【第17章:Java数据库编程】_处理大数据对象(1)—处理CLOB数据笔记.pdf ...

    列车管理系统

    第一章 列车车次管理系统需求分析 2 1.1 需求分析和概述 2 1.2 系统分析 2 第二章 数据库的设计 4 2.1 E-R图 4 2.2 表的结构说明 4 第三章 前台主界面的设计 5 3.1主界面概述 5 3.2前台主界面的实现 5 3.3数据库的...

    java经典面试2010集锦100题(不看你后悔)

    下面对程序的横线处填写不同语句的分析正确的是:(选择一项) A) 填充 break 使程序能够有退出循环的可能性。 B) 填充 continue 将使程序成为死循环,永远无法退出循环。 C) 填充 continue 使程序能够有退出循环的...

    dangdang和smartstruts2.rar

    ResultSet rs=pst.executeQuery();这个就是执行语句 写main.jsp.按照左中右的方式依次制定对应的action。 <!--左栏开始--> <s:action name="category" namespace="/main" executeResult="true"></s:action> ...

    mysql官方中文参考手册

    MySQL 5.1参考手册 目录 前言 1. 一般信息 1.1. 关于本手册 1.2. 本手册采用的惯例 1.3. MySQL AB概述 1.4. MySQL数据库管理系统概述 1.4.1. MySQL的历史 1.4.2. MySQL的的主要特性 1.4.3. MySQL稳定性 ...

    MYSQL中文手册

    言 1. 一般信息 1.1. 关于本手册 1.2. 本手册采用的惯例 1.3. MySQL AB概述 1.4. MySQL数据库管理系统概述 ...5.10.5....5.10.6....5.10.7....5.10.8....5.11.4....5.11.5....7.4.9....7.4.10....10.3.12....10.10.6....10.10.7....

    MySQL 5.1参考手册中文版

    目录 前言 1. 一般信息 1.1. 关于本手册 1.2. 本手册采用的惯例 1.3. MySQL AB概述 1.4. MySQL数据库管理系统概述 1.4.1. MySQL的历史 1.4.2. MySQL的的主要特性 1.4.3. MySQL稳定性 ...

Global site tag (gtag.js) - Google Analytics