原文链接:https://yq.aliyun.com/wenzhang/show_111763

问题描述

 //代码...

 ResultSet rs = this.conn.prepareStatement("select * from test1").executeQuery();

 //注sql语句不同

 while(rs.next()){  ...}

 rs = this.conn.prepareStatement("select * from test2").executeQuery();

 //注sql语句不同

 while(rs.next()){  ...}

 rs = this.conn.prepareStatement("select * from test3").executeQuery();

 //注sql语句不同

 while(rs.next()){  ...}

 rs.getStatement().close();

//疑问1:多次使用rs对象后,我在最后关闭一次,这样有没有问题?还是要每次用完都关闭(如上代码要关3次rs?)

//疑问2:使用rs.getStatement().close();关闭前,有没有必要先使用rs.close();关闭,每次都是吗(如上代码要关3次rs?)?

高手回答:

  

解决方案

  正常情况下如果使用Statement执行完一个查询,又去执行另一个查询时这时候第一个查询的结果集就会被关闭,也就是说,所有的Statement的查询对应的结果集是一个,如果调用Connection的commit()方法也会关闭结果集。可保持性就是指当ResultSet的结果被提交时,是被关闭还是不被关闭。JDBC2.0和1.0提供的都是提交后ResultSet就会被关闭。不过在JDBC3.0中,我们可以设置ResultSet是否关闭。要完成这样的ResultSet的对象的创建,要使用的Statement的创建要具有三个参数,这个Statement的创建方式也就是,我所说的Statement的第三种创建方式。如下:Statement st=createStatement(int resultsetscrollable,int resultsetupdateable,int resultsetSetHoldability)ResultSet rs = st.excuteQuery(sqlStr);前两个参数和两个参数的createStatement方法中的参数是完全相同的,这里只介绍第三个参数: resultSetHoldability表示在结果集提交后结果集是否打开,取值有两个: ResultSet.HOLD_CURSORS_OVER_COMMIT:表示修改提交时,不关闭数据库。 ResultSet.CLOSE_CURSORS_AT_COMMIT:表示修改提交时ResultSet关闭。
解决方案二:
  所以对于你的疑问要看具体的情况,一般情况下是没错的,不过为了便于阅读和理解程序,我们习惯还是最好关闭,如果是多个记录集最好是对应多个Statement
解决方案三:
  引用每次用完都关闭的话,它会立即释放此 ResultSet 对象的数据库和 JDBC 资源 如果在最后关闭的话,只是释放了最后这次查询的ResultSet,JDBC 资源. 如果不关闭的话,就会等待该对象自动关闭时(垃圾收集)发生释放此 ResultSet 对象的数据库和 JDBC 资源此操作。 rs.getStatement().close();自动导致ResultSet对象无效 注意只是ResultSet对象无效,ResultSet所占用的资源可能还没有释放,所有最好还是调有rs.close() 不执行ResultSet的close可能会导致更多的资源泄露

  SUN: An application calls the method Statement.close to indicate that it has finished processing a statement. All Statement objects will be closed when the connection that created them is closed. However, it is good coding practice for applications to close statements as soon as they have finished processing them. This allows any external resources that the statement is using to be released immediately. Closing a Statement object will close and invalidate any instances of ResultSet produced by that Statement object. The resources held by the ResultSet object may not be released until garbage collection runs again, so it is a good practice to explicitly close ResultSet objects when they are no longer needed. These comments about closing Statement objects apply to PreparedStatement and CallableStatement objects as well.

疑问:

  上面这位老兄说的我有点不赞同,我们可以写一个程序来测试一下,

rs=stmt.executeQuery("select * from test1 ");
rs2=stmt.executeQuery("select * from test2 "); while(rs2.next()){
System.out.println(rs2.getString(1));
System.out.println(rs2.getString(2));} while(rs.next()){
System.out.println(rs.getString(1));
System.out.println(rs.getString(2));
}  

  前面和后面我都不写了,假如你用这个测试的,会直接报Operation not allowed after ResultSet closed,那从这个异常我们就可以看出,在你进行操作的时候,你前一个rs已经被自动关闭了,所以说是“正常情况下如果使用Statement执行完一个查询,又去执行另一个查询时这时候第一个查询的结果集就会被关闭”。
解决方案四:
  每次用完都关闭的话,它会立即释放此 ResultSet 对象的数据库和 JDBC 资源如果在最后关闭的话,只是释放了最后这次查询的ResultSet,JDBC 资源.如果不关闭的话,就会等待该对象自动关闭时(垃圾收集)发生释放此 ResultSet 对象的数据库和 JDBC 资源此操作。 rs.getStatement().close();自动导致ResultSet对象无效 注意只是ResultSet对象无效,ResultSet所占用的资源可能还没有释放,所有最好还是调有rs.close()不执行ResultSet的close可能会导致更多的资源泄露。

SUN:An application calls the method Statement.close to indicate that it has finished processing a statement. All Statement objects will be closed when the connection that created them is closed. However, it is good coding practice for applications to close statements as soon as they have finished processing them. This allows any external resources that the statement is using to be released immediately. Closing a Statement object will close and invalidate any instances of ResultSet produced by that Statement object. The resources held by the ResultSet object may not be released until garbage collection runs again, so it is a good practice to explicitly close ResultSet objects when they are no longer needed. These comments about closing Statement objects apply to PreparedStatement and CallableStatement objects as well.

JDBC,ResultSet对像多次使用后再关闭的问题的更多相关文章

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

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

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

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

  3. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了

    JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...

  4. 个人学习记录1:二维数组保存到cookie后再读取

    二维数组保存到cookie后再读取 var heartsArray = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0, ...

  5. iOS 多个异步网络请求全部返回后再执行具体逻辑的方法

    对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...

  6. hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了

    hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了 例如session.save(user);user.setAge(20); 原因: hibernate对象的三种 ...

  7. MVC导出数据到EXCEL新方法:将视图或分部视图转换为HTML后再直接返回FileResult

    导出EXCEL方法总结 MVC导出数据到EXCEL的方法有很多种,常见的是: 1.采用EXCEL COM组件来动态生成XLS文件并保存到服务器上,然后转到该文件存放路径即可: 优点:可设置丰富的EXC ...

  8. JS的toFixed方法设置小数点位数后再进行计算,数据出错问题

    这个应该算作失真,或者也不算.情况就是用了toFixed后再进行相关计算,得不到预期的结果 具体看例子 比如想动态计算百分比,保留一位小数如94.4%这样子 var blobTo = 409600; ...

  9. C# 多线程join的用法,等待多个子线程结束后再执行主线程

    等待多个子线程结束后再执行主线程 class MultiThread{ #region join test public void MultiThreadTest() { Thread[] ths = ...

随机推荐

  1. vDom和domDiff

    虚拟dom和domDiff 1. 构建虚拟DOM var tree = el('div', {'id': 'container'}, [ el('h1', {style: 'color: blue'} ...

  2. eshop5-maven 安装

    1. Maven 安装 2.下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.0.5/binaries/ 3. 通过ta ...

  3. 利用jQuery实现PC端href生效,移动端href失效

    今天要写一个功能,记录一下吧.if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){ $('.item-a').attr('href' ...

  4. ffmpeg 知识点

    ffmpeg FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/ ...

  5. window下Apache Jmeter基础用法

    1.下载Apache-jmeter-5.1.1.zip 2.解压到一个地方,就可以开始使用了,如果需要在CMD里快速打开,可以设置环境变量. 3.在bin里面,直接打开jmeter.bat. 可以修改 ...

  6. 08 SSM整合案例(企业权限管理系统):06.产品操作

    04.AdminLTE的基本介绍 05.SSM整合案例的基本介绍 06.产品操作 07.订单操作 08.用户操作 09.权限控制 10.权限关联与控制 11.AOP日志 06.产品操作 SSM 环境搭 ...

  7. Python+Selenium中级篇之8-Python自定义封装一个简单的Log类《转载》

    Python+Selenium中级篇之8-Python自定义封装一个简单的Log类: https://blog.csdn.net/u011541946/article/details/70198676

  8. Git详细命令

    Git Guidegit的三种方式只在本地使用:将本地仓库上传到Github:下载GitHub上的仓库:1.只在本地使用在Git Bush上输入命令 mkdir git-demo-1 ——创建一个目录 ...

  9. 017-PHP数组形式读取TXT记事本内容

    <?php // 打开文件同时,输出每一行 $myFile = file("data.txt"); for ($index = 0; $index < count($m ...

  10. Windows系统安装免费的开源虚拟机软件VirtualBox

    https://www.qikegu.com/uncategorized/1179 VirtualBox是什么 VirtualBox是一个虚拟机平台软件,在VirtualBox平台上可以安装各种操作系 ...