`
阅读更多

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!!!。这就奇怪了,我明明没有关闭为什么还说关闭了呢,看看网上的解释和处理意见:

JDBC数据库连接池connection关闭后Statement和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 转换为JAVABEAN的工具类

    在Java编程中,ResultSet是处理数据库查询结果的主要接口,它由Statement或PreparedStatement对象执行SQL查询后返回。而JavaBean是一种符合特定规范的Java类,通常用于封装数据,便于数据的传输和操作。当我们从...

    java数据库连接ResultSet

    Java 数据库连接 ResultSet Java 数据库连接中的 ResultSet 是一个非常重要的概念,它包含符合 SQL 语句中条件的所有行,并且提供了对这些行中数据的访问。ResultSet 通过一套 get 方法访问当前行中的不同列,例如 ...

    java 使ResultSet转换List代码,绝对好用

    java 使ResultSet转换List代码,绝对好用 方便类型转换 不促之处,请提意见

    javaResultSet常用方法.pdf

    Java ResultSet常用方法 Java ResultSet是Java数据库连接(JDBC)中最重要的组件之一,用于存储和处理数据库查询结果。在Java中,ResultSet对象是通过Statement对象的executeQuery()方法或prepareStatement()方法...

    ResultSet转化为json,json转化为List

    在Java编程中,数据处理是核心任务之一,而ResultSet、JSON和List是处理数据时常见的三种数据结构。ResultSet是数据库查询结果的载体,JSON是一种轻量级的数据交换格式,而List是Java集合框架中的动态数组。本文将...

    java中ResultSet遍历数据操作

    Java 中 ResultSet 遍历数据操作 在 Java 中,ResultSet 是一个常用的数据库查询结果集对象,它提供了遍历数据操作的功能,下面我们将对 ResultSet 遍历数据操作进行详细的介绍。 一、 获取数据库表的列名 在 ...

    java ResultSet 与 json互转所需要的全部包资源

    在java开发中常需要将ResultSet结果集转化为json格式以实现与客服端实现数据交互,但是这需要几个包,而且版本也要对应,因此我收集了全部的包,并测试可以运行,放在这里供大家下载。包括:commons-beanutils-1.7.0...

    ResultSet 转为listmap

    在 Java 中,使用 JDBC 连接数据库时,通常会返回一个 ResultSet 对象,该对象包含了查询结果集的所有记录。为了方便数据处理和使用,我们需要将 ResultSet 转为 List,以便于后续的数据处理和展示。 下面是将 ...

    java resultset常用方法

    ### Java ResultSet 常用方法详解 #### 一、ResultSet 类型概述 在Java的JDBC编程中,`ResultSet`接口用于表示从数据库查询中获取的结果集。它提供了多种方式来处理这些数据,并且根据不同的应用场景,支持不同类型...

    java sql ResultSet 之getRow()用法说明

    Java SQL ResultSet 之 getRow() 用法说明 在 Java 中,当我们使用 SQL 语句查询数据库时,通常会使用 ResultSet 对象来存储查询结果。其中,getRow() 方法是一个非常重要的方法,它可以返回当前指针所在的行号。...

    如何从 Java 存储过程将 JDBC ResultSet 作为 Ref Cursor 返回.doc

    在Oracle9i之前的版本,直接从Java存储过程返回ResultSet是不被支持的,因为缺乏ResultSet到REF CURSOR的映射机制。然而,Oracle9i引入了这种映射,使得Java存储过程能够返回ResultSet或作为OUT参数传递。尽管如此,...

    java组件开发(15) JDBC操作工具类与ResultSet数据

    java组件开发(15) JDBC操作工具类与ResultSet数据

    ResultSet

    ResultSet是Java数据库连接(JDBC)中的核心接口,它用于存储和检索数据库查询结果。当你执行SQL查询并从数据库获取数据时,结果会被封装在ResultSet对象中。在本篇文章中,我们将深入探讨ResultSet的主要概念、操作...

    JdbcSql.rar_java resultset_jtable

    使用JDBC时,我们需要导入`java.sql.*`包下的相关类,如`DriverManager`、`Connection`、`Statement`和`ResultSet`。 2. **ResultSet**: `ResultSet`是执行SQL查询后返回的结果集,它是一个接口,用于存储查询结果...

    ResultSet的属性

    ResultSet是Java数据库连接(JDBC)中的一个重要接口,它用于存储和检索数据库查询结果。当执行SQL查询后,结果会被封装成ResultSet对象,允许我们逐行遍历并访问查询返回的数据。在处理ResultSet时,了解其属性和元...

    Java ResultSet导出大数据.docx

    本文主要探讨如何有效地解决这个问题,特别是针对Java中的ResultSet对象。 首先,对于Excel导出,传统的API如Apache POI和JXL在处理大数据时,由于它们在内存中构建的Excel对象远大于原始数据大小,可能导致内存...

    poi根据ResultSet到处Excle源码

    标题中的“poi根据ResultSet到处Excle源码”指的是使用Java的Apache POI库将数据库查询结果(ResultSet)转换为Excel文件的过程。Apache POI是一个流行的API,它允许开发者读写Microsoft Office格式的文件,包括...

    Java ResultSet导出大数据.pdf

    总的来说,处理大数据时,Java程序员需要理解数据库的行为,熟练使用ResultSet的特性,并结合合适的文件导出策略,以确保程序在内存、CPU和磁盘IO之间达到良好的平衡。同时,监控系统资源和性能指标,以及进行针对性...

Global site tag (gtag.js) - Google Analytics