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);
分享到:
相关推荐
JDBC 解析JDBC中文API各种数据库之间的链接问题,网络编程
JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单写法JDBC简单...
JDBC中操作Blob、Clob等对象 实例详细JDBC中操作Blob、Clob等对象 实例详细JDBC中操作Blob、Clob等对象 实例详细JDBC中操作Blob、Clob等对象 实例详细JDBC中操作Blob、Clob等对象 实例详细JDBC中操作Blob、Clob等...
JDBC中的dao的标准写法,本人还在完善中,待完善后会全部上传,欢迎大家参考。
jdbc jdbc jdbc jdbc jdbc jdbc jdbc jdbc
JDBC代码 JDBC代码JDBC代码 JDBC代码
Java JDBC常考知识点 1. JDBC(Java Database Connectivity,Java 数据库连接)是一套用于执行 SQL ...程序中由 JDBC 和具体的数据库驱动联系,这样应用程序就不必直接与底层的数据库交互,从而使代 码的通用性更强。
JDBC规范 java.sql和javax.sql两个包中的类与接口(天龙八部): DataSource:数据源 DriverManager:驱动管理 Driver:JDBC驱动 Connection:数据库连接 Statement:语句,执行SQL PrepareStatement:...
JDBC中动态拼接SQL的工具类。 对于使用纯SQL访问数据库的同学会有些帮助。 并具有一定的扩展性。
JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础
jdbc (java数据库连接)中文参考文档 chm格式
MySQL JDBC 彻底 解决 中文乱码问题 MySQL JDBC 彻底 解决 中文乱码问题
hive-jdbc
JDBC笔记 JDBC笔记 JDBC笔记
jdbc中常见异常原因以及解决方法 jdbc中常见异常原因以及解决方法
jdbc资料jdbc资料jdbc资料jdbc资料
Java连接达梦数据库驱动dm_jdbc: dm_jdbc\com.dameng.floader.jar dm_jdbc\com.dameng.impexp.jar dm_jdbc\Dm7Dictionary.jar dm_jdbc\Dm7JdbcDriver14.jar dm_jdbc\Dm7JdbcDriver15.jar dm_jdbc\Dm7JdbcDriver16....
赠送jar包:sqlite-jdbc-3.15.1.jar; 赠送原API文档:sqlite-jdbc-3.15.1-javadoc.jar; 赠送源代码:sqlite-jdbc-3.15.1-sources.jar;...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
JDBC高级应用JDBC高级应用JDBC高级应用JDBC高级应用
1、在应用中jdbc url最前面添加jdbc:log4;比如oracle的url就变成了jdbc:log4jdbc:oracle:thin:@x.x.x.x:1521:dbname; 2、在日志系统中设置jdbc.sqlonly、jdbc.sqltiming等日志级别,可直接将log4jdbc doc中的日志...