Java当中的ResultSet是什么、干什么用就不多说了,说说我前几天在这里栽的一个跟头。
先上一段测试代码看看问题:
public class TestResult { public static void main(String[] args){ String sql = "select id,username from s_user"; ResultSet rs = null; try{ rs = execQuery(sql); while(rs.next()){ System.out.println("序号:"+rs.getInt(1)+"\t用户名:"+rs.getString(2)); } }catch(Exception e){ e.printStackTrace(); }finally{ closeResultSet(rs); } } /** * 该方法用来执行查询sql * @param sql:要执行查询的sql * @return ResultSet:结果集合 * */ public static ResultSet execQuery(String sql){ Connection conn=null;//连接 PreparedStatement pst= null; ResultSet rs=null; try{ conn = com.wjl.C3P0Dao.getConn(); if(conn!=null){ pst = conn.prepareStatement(sql); rs = pst.executeQuery(); } }catch(Exception e){ e.printStackTrace(); }finally{ System.out.println("1111111111111111"); closeConn(rs,pst,conn); } System.out.println("22222222222222"); return rs; } /** * 资源关闭 * @param rs * @param stmt * @param conn */ public static void closeConn(ResultSet rs, Statement stmt, Connection conn) { if (rs != null) { try {rs.close(); } catch (SQLException e){e.printStackTrace();} } if (stmt != null) { try {stmt.close(); } catch (SQLException e){e.printStackTrace();} } if (conn != null) { try {conn.close(); } catch (SQLException e) {e.printStackTrace();} } } /** * 资源关闭 */ public static void closeResultSet(ResultSet rs) { if (rs != null) { try {rs.close(); } catch (SQLException e) {e.printStackTrace();} } } }
以上是一个再寻常不过的JDBC查询代码了,这个代码看似没有问题,但运行起来准报错:You can't operate on a closed ResultSet!!!。因为finally执行在return之前,return之前rs就已经关闭了,自然就无法操作一个已经关闭了的ResultSet了。那我不关闭ResultSet不就完了,于是注释掉closeConn()方法中关闭ResultSet那一段,再执行,依旧报错:You can't operate on a closed ResultSet!!!。这就奇怪了,我明明没有关闭为什么还说关闭了呢,看看网上的解释和处理意见:
1.垃圾回收机制可以自动关闭它们;
2.Statement关闭会导致ResultSet关闭;
3.Connection关闭不一定会导致Statement关闭。
V6使用的是数据库连接池,Connection关闭并不是物理关闭,只是归还连接池,所以Statement和ResultSet有可能被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行就有可能报“游标超出数据库允许的最大值”的错误,导致程序无法正常访问数据库。
解决建议:
(1)由于垃圾回收的线程级别是最低的,为了充分利用数据库资源,有必要显式关闭它们,尤其是使用Connection Pool的时候;
(2)最优经验是按照ResultSet,Statement,Connection的顺序执行close;
(3)为了避免由于java代码有问题导致内存泄露,需要在rs.close()和stmt.close()后面一定要加上rs = null和stmt = null;
(4) 如果一定要传递ResultSet,应该使用RowSet,RowSet可以不依赖于Connection和Statement。Java传递的是引用,所以如果传递ResultSet,你会不知道Statement和Connection何时关闭,不知道ResultSet何时有效。
( 引用链接:http://blog.csdn.net/hantiannan/article/details/7904855)
根据建议,使用RowSet来代替ResultSet返回数据。
Rowset的使用:http://blog.csdn.net/id19870510/article/details/5988438
RowSet和ResultSet的区别:http://blog.csdn.net/amaryh/article/details/5256090
根据RowSet各个接口的特性,推荐使用CachedRowSet,这个是不与statement和Connection关联的,即使前两个关闭了它已经能用。因此将上面的代码改成使用CachedRowSet来返回数据,代码如下:
public class TestResult2 { public static void main(String[] args){ String sql = "select id,username from s_user"; CachedRowSetImpl rs = null; try{ rs = execQuery(sql); while(rs.next()){ System.out.println("序号:"+rs.getInt(1)+"\t用户名:"+rs.getString(2)); } }catch(Exception e){ e.printStackTrace(); }finally{ closeCachedRowSet(rs); } } /** * 该方法用来执行查询sql * @param sql:要执行查询的sql * @return CachedRowSetImpl:结果集合 * */ public static CachedRowSetImpl execQuery(String sql){ Connection conn=null;//连接 PreparedStatement pst= null; ResultSet rs=null; CachedRowSetImpl rowset = null; try{ conn = com.wjl.C3P0Dao.getConn(); if(conn!=null){ pst = conn.prepareStatement(sql); rowset=new CachedRowSetImpl(); rowset.populate(pst.executeQuery()); } }catch(Exception e){ e.printStackTrace(); }finally{ closeConn(rs,pst,conn); } return rowset; } /** * 资源关闭 * @param rs * @param stmt * @param conn */ public static void closeConn(ResultSet rs, Statement stmt, Connection conn) { ...... } /** * 资源关闭 * @param CachedRowSetImpl rs */ public static void closeCachedRowSet(CachedRowSetImpl rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
另外,也可以使用Result来代替ResultSet返回数据,具体使用方法可以参考如下链接:
http://www.cnblogs.com/zzlp/p/5120176.html
祝大家好运!
相关推荐
在Java编程中,ResultSet是处理数据库查询结果的主要接口,它由Statement或PreparedStatement对象执行SQL查询后返回。而JavaBean是一种符合特定规范的Java类,通常用于封装数据,便于数据的传输和操作。当我们从...
Java 数据库连接 ResultSet Java 数据库连接中的 ResultSet 是一个非常重要的概念,它包含符合 SQL 语句中条件的所有行,并且提供了对这些行中数据的访问。ResultSet 通过一套 get 方法访问当前行中的不同列,例如 ...
java 使ResultSet转换List代码,绝对好用 方便类型转换 不促之处,请提意见
Java ResultSet常用方法 Java ResultSet是Java数据库连接(JDBC)中最重要的组件之一,用于存储和处理数据库查询结果。在Java中,ResultSet对象是通过Statement对象的executeQuery()方法或prepareStatement()方法...
在Java编程中,数据处理是核心任务之一,而ResultSet、JSON和List是处理数据时常见的三种数据结构。ResultSet是数据库查询结果的载体,JSON是一种轻量级的数据交换格式,而List是Java集合框架中的动态数组。本文将...
Java 中 ResultSet 遍历数据操作 在 Java 中,ResultSet 是一个常用的数据库查询结果集对象,它提供了遍历数据操作的功能,下面我们将对 ResultSet 遍历数据操作进行详细的介绍。 一、 获取数据库表的列名 在 ...
在java开发中常需要将ResultSet结果集转化为json格式以实现与客服端实现数据交互,但是这需要几个包,而且版本也要对应,因此我收集了全部的包,并测试可以运行,放在这里供大家下载。包括:commons-beanutils-1.7.0...
在 Java 中,使用 JDBC 连接数据库时,通常会返回一个 ResultSet 对象,该对象包含了查询结果集的所有记录。为了方便数据处理和使用,我们需要将 ResultSet 转为 List,以便于后续的数据处理和展示。 下面是将 ...
### Java ResultSet 常用方法详解 #### 一、ResultSet 类型概述 在Java的JDBC编程中,`ResultSet`接口用于表示从数据库查询中获取的结果集。它提供了多种方式来处理这些数据,并且根据不同的应用场景,支持不同类型...
Java SQL ResultSet 之 getRow() 用法说明 在 Java 中,当我们使用 SQL 语句查询数据库时,通常会使用 ResultSet 对象来存储查询结果。其中,getRow() 方法是一个非常重要的方法,它可以返回当前指针所在的行号。...
在Oracle9i之前的版本,直接从Java存储过程返回ResultSet是不被支持的,因为缺乏ResultSet到REF CURSOR的映射机制。然而,Oracle9i引入了这种映射,使得Java存储过程能够返回ResultSet或作为OUT参数传递。尽管如此,...
java组件开发(15) JDBC操作工具类与ResultSet数据
ResultSet是Java数据库连接(JDBC)中的核心接口,它用于存储和检索数据库查询结果。当你执行SQL查询并从数据库获取数据时,结果会被封装在ResultSet对象中。在本篇文章中,我们将深入探讨ResultSet的主要概念、操作...
使用JDBC时,我们需要导入`java.sql.*`包下的相关类,如`DriverManager`、`Connection`、`Statement`和`ResultSet`。 2. **ResultSet**: `ResultSet`是执行SQL查询后返回的结果集,它是一个接口,用于存储查询结果...
ResultSet是Java数据库连接(JDBC)中的一个重要接口,它用于存储和检索数据库查询结果。当执行SQL查询后,结果会被封装成ResultSet对象,允许我们逐行遍历并访问查询返回的数据。在处理ResultSet时,了解其属性和元...
本文主要探讨如何有效地解决这个问题,特别是针对Java中的ResultSet对象。 首先,对于Excel导出,传统的API如Apache POI和JXL在处理大数据时,由于它们在内存中构建的Excel对象远大于原始数据大小,可能导致内存...
标题中的“poi根据ResultSet到处Excle源码”指的是使用Java的Apache POI库将数据库查询结果(ResultSet)转换为Excel文件的过程。Apache POI是一个流行的API,它允许开发者读写Microsoft Office格式的文件,包括...
总的来说,处理大数据时,Java程序员需要理解数据库的行为,熟练使用ResultSet的特性,并结合合适的文件导出策略,以确保程序在内存、CPU和磁盘IO之间达到良好的平衡。同时,监控系统资源和性能指标,以及进行针对性...