Java JDBC ResultSet已关闭

时间:2014-05-06 05:50:33

标签: java sql sqlite jdbc

运行此代码时,我收到ResultSet关闭错误。被调用的方法和数据如下:

日志输出:

[2014-05-05 22:34:09.169 Debug] select count(*) as total from companies
[2014-05-05 22:34:09.170 Debug] ResultSet closed

方法:

public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        ResultSet resultset = queryDB(sql, c);
        resultset.next();
        int count = resultset.getInt(1);
        Log.debug(Integer.toString(count));
        resultset.close();
        if (count > 0) {
            Log.debug("recordsExist returning true");
            return true;
        } else {
            Log.debug("recordsExist returning false");
            return false;
        }

    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static ResultSet queryDB(String sql, Connection c) throws SQLException {
    Log.debug(sql);
    Statement s = c.createStatement();
    ResultSet resultset = s.executeQuery(sql);
    s.close();
    return resultset;
}

指定的SQL字符串:

select * from companies

3 个答案:

答案 0 :(得分:3)

来自Java API

  

注意:当Statement对象关闭时,它的当前ResultSet对象(如果存在)也将关闭。

在关闭Statement之前,您需要处理ResultSet中的数据。这些方面应该有用:

public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        return queryDB(sql, c);


    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static boolean queryDB(String sql, Connection c) throws SQLException {
    Log.debug(sql);
    Statement s = c.createStatement();
    ResultSet resultset = s.executeQuery(sql);
    boolean result = processResult(resultset);
    s.close();
    return result;
}

public static boolean processResult(ResultSet resultset) {
    resultset.next();
    int count = resultset.getInt(1);
    Log.debug(Integer.toString(count));
    resultset.close(); 
    if (count > 0) {
        Log.debug("recordsExist returning true");
        return true;
    } else {
        Log.debug("recordsExist returning false");
        return false;
    }

}

我还会考虑添加更多错误处理,以确保您不会泄漏资源。例如,如果在处理结果时发生异常,则您的语句将无法正确关闭。

答案 1 :(得分:1)

不要关闭声明。 场景就像第一次关闭结果集然后语句写下这样的代码:

    public static Boolean recordsExist(String string, Connection c) {
    try {
        String[] query = string.split("\\*");
        String sql = "select count(*) as total" + query[1];
        Statement s = c.createStatement();
        ResultSet resultset = queryDB(sql, c, s);
        resultset.next();
        int count = resultset.getInt(1);
        Log.debug(Integer.toString(count));
        resultset.close();
        s.close();
        if (count > 0) {
            Log.debug("recordsExist returning true");
            return true;
        } else {
            Log.debug("recordsExist returning false");
            return false;
        }

    } catch (Exception e) {
        Log.debug(e.getMessage());
        return false;
    }
}

public static ResultSet queryDB(String sql, Connection c, Statement s ) throws SQLException {
    Log.debug(sql);
    ResultSet resultset = s.executeQuery(sql);
    return resultset;
}

答案 2 :(得分:1)

请务必先检查下一个结果集,如下所示

 if(resultset.next()){
     int count = resultset.getInt(1);
 }
  

我已经发布了一个很好的ConnectionUtil类来管理整个应用程序的单个类中的所有连接。


关闭最后Statement子句中的ResultSetConnectionfinally,以确保在任何情况下都关闭所有内容,如下面的代码所示。

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    ...
} finally {
    if (rs != null) {
        rs.close();
    }
    if (stmt != null) {
        stmt.close();
    }
    if (conn != null) {
        conn.close();
    }
} 

注意:请勿将Log.debug(e.getMessage());用于ERROR消息,否则您将在日志中丢失以查找错误。