原文链接: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. php 获取时间段

    switch ($type){ case 'day'://当日 $end=date(,,,date(,date('Y'))); $where=' and '.$pre.'create_time> ...

  2. Spring的AOP开发(基于ApsectJ的注解)

    创建项目,导包 编写目标类并配置 创建OrderDao package com.rick.aop.demo1; public class OrderDao { public void save() { ...

  3. Netty 异步模型

    简介 Netty中的 I/O 操作是异步的, 包括 Bind.Write.Connect 等操作会简单的返回一个ChannelFuture. 调用者不能立刻获得结果, 而是通过Future-Liste ...

  4. Arrays类常用方法

    Arrays类 3.1 概述 java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等.其所有方法均为静态方法. 3.2 操作数组的方法 1.将参数数组变成字符串 publi ...

  5. 吴裕雄--天生自然java开发常用类库学习笔记:同步与死锁

    class MyThread implements Runnable{ private int ticket = 5 ; // 假设一共有5张票 public void run(){ for(int ...

  6. Set Request Header

    第1步 webpack package.json 的 scripts 里的 dev 要新增 --host 0.0.0.0 这样在浏览器里用ip地址代替localhost就能运行了 第2步 在pc浏览器 ...

  7. ajax异步请求数据

    源码1: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  8. [LeetCode] 932. Beautiful Array 漂亮数组

    For some fixed N, an array A is beautiful if it is a permutation of the integers 1, 2, ..., N, such ...

  9. ADLS_pppoe 基本设置过程

    ADLS_pppoe 设置: ①:开启接口的PPPoe功能——pppoe enable ②:指明接口是拨号池1的成员——pppo-client dial-pool-number ③:创建一个逻辑上的拨 ...

  10. Linux基础操作及概念

    Linux基础操作及概念 终端的概念 通常我们在使用 Linux 时,并不是直接与系统打交道,而是通过一个叫做 Shell 的中间程序来完成的,在图形界面下为了实现让我们在一个窗口中完成用户输入和显示 ...