引言
在做底层的时候,出现这样一个问题: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类型等等。