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 |
程序如下:
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 的问题。调用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);
转自 http://www.java3z.com/cwbwebhome/article/article8/828.html?id=2244
相关推荐
- 创建滚动结果集,可以使用 `Statement` 的构造函数指定结果集类型,如 `createStatement(int resultSetType, int resultSetConcurrency)`。 - 结果集的滚动方法包括 `next()`, `previous()`, `first()`, `last()...
- `createStatement(int resultSetType, int resultSetConcurrency)`:创建一个带有特定类型和并发性的`Statement`对象。 - `commit()`:提交对数据库的更改。 - `rollback()`:撤销当前事务中的所有更改。 - `...
### JDBC学习文档知识点详解 #### 一、JDBC概述与基本概念 JDBC(Java Database Connectivity)是Java中用于操作数据库的一种标准API,它提供了一系列的接口和类,允许Java程序连接并操作各种类型的数据库系统。...
这通过设置`Statement`的`ResultSetConcurrency`和`ResultSetType`属性实现,例如,`ResultSet.TYPE_SCROLL_INSENSITIVE`和`ResultSet.CONCUR_UPDATABLE`组合可以创建一个可滚动且可更新的结果集。 批处理更新...
- **获取JDBC驱动文件**:通过访问数据库厂商的官方网站,下载对应的JDBC驱动文件以及相关的文档说明。这些驱动文件通常是`.jar`格式的Java归档文件。 - **添加驱动文件到classpath**: - **对于Java Web项目**:...
- 执行计划缓存:启用Statement对象的`prepareCall(String sql, int resultSetType, int resultSetConcurrency)`,以缓存执行计划。 - 并行执行:使用多个连接并发执行SQL。 - 延迟加载:只在需要时加载结果集...
- `createStatement(int resultSetType, int resultSetConcurrency)`:允许自定义结果集的类型和并发性。 7. **结果集(ResultSet)**: ResultSet对象是执行SQL查询后返回的结果。它有几种类型和并发级别: - `...
游动查询的两个关键参数是resultSetType和resultSetConcurrency,前者决定游标是否可以上下移动,后者确定结果集是否可以用于更新数据库。例如,ResultSet.TYPE_FORWARD_ONLY表示只能向下移动,不支持回滚;...
**DriverManager** 类是 Java JDBC (Java Database Connectivity) API 的一部分,其主要职责在于管理和维护数据库驱动程序。它作为用户与驱动程序之间的桥梁,允许用户通过简单的方法来加载和访问不同的数据库。 - ...
package com.ibatis.common.jdbc; // Imports import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.sql.CallableStatement; import java.sql.Connection; import java.sql....
Java中的`ResultSet`是JDBC(Java Database Connectivity)API的核心组件之一,用于存储从数据库查询中获取的结果。它是一个从`Statement`或`PreparedStatement`执行SQL查询后返回的对象,包含了查询结果的一系列行...
- `resultSetType`:设置`ResultSet`的滚动模式,`ResultSet.TYPE_FORWARD_ONLY`表示仅支持前向滚动,`ResultSet.TYPE_SCROLL_INSENSITIVE`和`ResultSet.TYPE_SCROLL_SENSITIVE`则允许双向滚动,区别在于后者对数据...
- **`Statement createStatement(int resultSetType, int resultSetConcurrency)`**:创建一个带有特定结果集类型和并发性的`Statement`对象,允许更细粒度地控制结果集的行为。 - **`void commit()`**:提交当前...
创建可滚动结果集的Statement对象,可以使用`Connection.createStatement(int resultSetType, int resultSetConcurrency)`,参数分别为`ResultSet.TYPE_SCROLL_INSENSITIVE`和`ResultSet.CONCUR_READ_ONLY`。...
* resultSetType:表示结果集的类型 3.3.2 元素 元素的属性包括: * KeyProperty:仅对insert和update标签有效,插入和更新操作时,返回值赋值给某个属性 * keyColumn:仅对insert和update标签有效,此属性用于...
│ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdbc.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.jdk14.html │ │ │ frame-sourcefiles-org.apache.ibatis.logging.log4j.html │ │ │ ...
- 使用 `ResultType` 或 `ResultSetType` 控制结果集的返回类型。 - 利用 MyBatis 提供的缓存机制提高性能。 7. **MyBatis 的优势** - 简化 JDBC 编程,减少手写 SQL 和结果映射代码。 - 提供了动态 SQL 功能,...