Operation not allowed after ResultSet closed--Mysql

来源:互联网 发布:审美疲劳 知乎 编辑:程序博客网 时间:2024/05/16 09:23

引言


在做底层的时候,出现这样一个问题: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 blocke.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 blocke.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 0
原创粉丝点击