JDBC 查询的三大参数
本文转载至 http://blog.csdn.net/turkeyzhou/article/details/5115228
DBC1.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) {
- }
- }
- }
- 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” ,而不是原始的“ 3c3 ”。但最终的结果却是如下:
[ 行号: 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 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
JDBC 查询的三大参数 本文转载至 http://blog.csdn.net/turkeyzhou/article/details/5115228 DBC1.0 .JDBC2.0 .JDBC3.0 ...
- spring jdbc 查询结果返回对象、对象列表
首先,需要了解spring jdbc查询时,有三种回调方式来处理查询的结果集.可以参考 使用spring的JdbcTemplate进行查询的三种回调方式的比较,写得还不错. 1.返回对象(queryF ...
- Redis查询&JDBC查询&Hibernate查询方式的效率比较...
比较三种查询方式查询效率对比...我是用的JavaWeb的方式通过通过JSP页面查询的填写查询的参数...给予反馈.... 整个demo的下载地址:http://files.cnblogs.com/f ...
- JDBC 查询 模板
JDBC 查询 与增删改不同的是SQL语句的不同,还有查询反回的是结果集 需要定义 利用 next()方法逐层查询数据 使用getXXX方法获取数据 代码相关参数根据个人设置进行修改!!!! pac ...
- c#数据绑定(4)——向查询中添加参数
本实例主要练习了ADO.Net 连接到外部数据库的基础上,向查询中添加参数.使用的是ACCESS数据库. 在ACCESS数据库中可以用MSSQL的形式定义操作字符串,也可以采用OLEDB的形式. MS ...
- Java 通过JDBC查询数据库表结构(字段名称,类型,长度等)
Java 通过JDBC查询数据库表结构(字段名称,类型,长度等) 发布者:唛唛家的豆子 时间:2012-11-20 17:54:02 Java 通过JDBC查询数据库表结构(字段名称,类型,长 ...
- MyBatis查询传一个参数时报错:There is no getter for property named 'sleevetype' in 'class java.lang.Integer
用MyBatis进行查询,传入参数只有一个时(非Map)如int,报错 There is no getter for property named 'sleevetype' in 'class jav ...
- 用JDBC查询数据库
JDBC API的核心组件:1.DriverManager类:用语跟踪可用的JDBC驱动程序并产生数据库连接. 2.Connection接口:用于取得数据库信息.生成数据库语句,并管理数据库事务. 3 ...
- 如何获取浏览器URL中查询字符串的参数
首先要知道Location这个对象以及这个对象中的一些属性: href:设置或返回完整的url.如本博客首页返回http://www.cnblogs.com/wymninja/ host:设置或返回主 ...
随机推荐
- C# Activex调用USB摄像头--附带源码
前言 最近在整理一些自己写过的东西,也算是重新熟悉一下并且优化一下吧. 需求:获取本地USB摄像头视频显示,并且获取图片数据给底层做人脸识别. 记得当时直接采用H5已经做好了,调试好了....结果放上 ...
- join方法的使用
在上面的例子中多次使用到了Thread类的join方法.我想大家可能已经猜出来join方法的功能是什么了.对,join方法的功能就是使异步执行的线程变成同步执行.也就是说,当调用线程实例的start方 ...
- Android-Binder原理浅析
Android-Binder原理浅析 学习自 <Android开发艺术探索> 写在前头 在上一章,我们简单的了解了一下Binder并且通过 AIDL完成了一个IPC的DEMO.你可能会好奇 ...
- 1722 最优乘车 1997年NOI全国竞赛
题目描述 Description H城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路.每条单程巴士线路从某个巴士 ...
- UOJ.179.线性规划(单纯形)
题目链接 这写得还不错:http://www.cnblogs.com/zzqsblog/p/5457091.html 引入基变量\(x_{i+n}\),将约束\(\sum_{i=1}^m a_{ij} ...
- Nancyfx框架在传统Webform项目中的应用
最近有个老项目需要做一个需求更迭,老项目是基于传统的webform项目的 为了更好的前后台交互,决定引入Nancyfx框架 关于Nancyfx框架框架是啥就不多介绍了 总的来说是一款轻量级的web框架 ...
- HDU 4436 str2int (后缀自动机SAM,多串建立)
str2int Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
- OpenOCD 0.9.0 release
OpenOCD 0.9.0 release May 18th, 2015 I’m happy to announce the release of OpenOCD version 0.9.0, fin ...
- 《Go语言实战》摘录:7.1 并发模式 - runner
7.1 并发模式 - runner
- office 2010 正在配置Microsoft Office ...
原因主要是安装时候所用账户和你目前登陆的账户不为同一个账户,或者你进行过覆盖安装或是重新安装过系统但是office得安装目录没有变. 解决方法:激活office----更改注册表--完成 [HKEY_ ...