Operation not allowed after ResultSet closed--Mysql

引言


在做底层的时候,出现这样一个问题:Operation not allowed after ResultSet closed(操作不允许在ResultSet关闭之后进行)。有两种可能出现下面的情况:


第一种情况:


错误代码:


<span style="font-family:KaiTi_GB2312;font-size:18px;">    /**
     * 查找
     * @param sql
     * @param sqlValues
     * @return
     */
    public  ResultSet executeQuery(){
    
    	ResultSet rst=null;
    	Statement  stmt =null;
    	try {
    	
    		stmt =con.createStatement();
    		rst = stmt.executeQuery(sql);
	
	    
	    
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			this.closeAll(con, stmt, rst);
		}		
    	return rst;
    }</span>

正确代码为:


<span style="font-family:KaiTi_GB2312;font-size:18px;">    /**
     * 查找
     * @param sql
     * @param sqlValues
     * @return
     */
    public  Result executeQuery(){   
    	ResultSet rst=null;
    	Statement  stmt =null;
    	Result result = null;
    	try {    	
    		stmt =con.createStatement();
    		rst = stmt.executeQuery(sql);			
	        result=ResultSupport.toResult(rst);  //一定要在关闭数据库之前完成转换*/			    
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			this.closeAll(con, stmt, rst);
		}		
    	return result;
    }</span>

其实可以看出来,在代码中ResultSet是厂区占用数据库连接的,而我们返回查询结果到业务层的时候,需要的是离线使用的,这样我们就需要将ResultSet类转为Result类即可。


我们使用的ResultSet来返回数据库查询结果是这样的:Client --> Connection --> Statement --> JDBC Driver --+   Database Client <-- Parsing <-- ResultSet <-- JDBCDriver --+  Connection lifecycle  ---> ResultSetlifecycle   .


因此,我们在写数据返回数据的时候,要将ResultSet转换为Result才可以进行返回使用,否则,就会出现这样Operation not allowed after ResultSet closed错误。


第二种情况:


错误代码:


<span style="font-family:KaiTi_GB2312;font-size:18px;"> stmt=conn.createStatement();
 
 rs=stmt.executeQuery("select * from t1");
 rst=stmt.executeQuery("select * from t2");
 
 rs.last();
    //由于执行了rst=stmt.executeQuery(sql_a);rs就会被关闭掉!所以程序执行到此会提示ResultSet已经关闭.错误信息为:java.sql.SQLException: Operation not allowed after ResultSet closed
 
rst.last();</span>

正确的代码:


<span style="font-family:KaiTi_GB2312;font-size:18px;">stmt=conn.createStatement();
 
rs=stmt.executeQuery("select * from t1");
rs.last();//对rs的操作应马上操作,操作完后再从数据库得到rst,再对rst操作
 
rst=stmt.executeQuery("select * from t2");
rst.last();</span>

就是说,一个statement对象多个ResultSet进行操作,那么statement得到的第一个ResultSet之后,才能去得到另外的ResultSet,再对ResultSet2操作,不能互相交替使用,否则也会出现Operation not allowed after ResultSet closed问题。


当然,我们也可以建立多个statement,一个statement对应一个ResultSet就可以了。


正确的代码:


<span style="font-family:KaiTi_GB2312;font-size:18px;">多个stmt对应各自的rs.
stmt=conn.createStatement();
stmt2=conn.createStatement();
 
rs=stmt.executeQuery("select * from t1");
rst=stmt2.executeQuery("select * from t2");
 
rs.last();
rst.last();</span>

结束语:


综上所述都是其实无非都是一个道理:就是我们关闭了ResultSet之后,仍然对ResultSet进行读取,而ResultSet是必须不能关闭才能使用的容器,因此,我们这里要继续转换,这里转换的方式有多种:可以转为Map类型、list类型、Result类型等等。







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值