【问题标题】:JDBC ResultSet closed in Java after several iterations经过几次迭代后,JDBC ResultSet 在 Java 中关闭
【发布时间】:2019-03-20 11:12:44
【问题描述】:

我在关闭 ResultSet 时遇到问题。让我感到困惑的是,它适用于部分数据然后关闭。起初我以为可能是因为连接超时,但事实并非如此。

该程序的这部分涉及将.xlsx 工作簿与已经存在的SQL 数据库进行比较,并且由于缺少更好的术语而合并/更新它。

首先,在我的 CompareDatabase 类中,我调用了一个搜索函数,该函数每 6 次迭代在 SQLite 数据库中搜索特定字符串。

int columnCount = 6;
dataPoint = dataPoint.replaceAll("Detail", "");
String[] temp = dataPoint.trim().split("\\s+");
System.out.println(Arrays.toString(temp));
for (String tempDataPoint : temp) {
    if ( columnCount == 6) {
         System.out.println(search(tempDataPoint, connection));
    }
    columnCount = 0;
    } else {
         columnCount++;
    }
}

这个搜索函数(也在CompareDatabase 类中然后应该搜索值并返回一个字符串(最初是一个布尔值,但我想查看输出)。

private String search (String searchValue, Connection connection) throws SQLException {
    PreparedStatement pStatement = null;
    pStatement = connection.prepareStatement("SELECT * FROM lotdatabase where (Vehicle) = (?)");
    pStatement.setString(1, searchValue);

    try (ResultSet resultSet = pStatement.executeQuery()){
        return resultSet.getString(1);
    }finally {
        close(pStatement);
    }
}

最后您可以看到PreparedStatement 已关闭。 ResultSet 也应该自动关闭(我在某处读过),但 JDBC 可能不可靠。

Connection 仍处于打开状态,因为它将搜索大约 200 多个字符串并且多次打开和关闭似乎不是一个好主意。

这些函数由我的main 类在这里调用: 一个被注释掉,因为它会因为违反主键而出错。

public static void main(String[] args) {
    SQLDatabase sqlDatabase = new SQLDatabase();
    //sqlDatabase.convertToSQL("Database1.xlsx");
    sqlDatabase.compare("Database2.xlsx");
}

我怀疑我正在处理一系列错误(在管理连接等方面),我希望能参考我可以在哪里学习如何正确地做到这一点。

另外,由于PreparedStatement 只能处理一个ResultSet,我不认为这是我的问题,因为我在for 循环中的每次迭代都关闭它。

如果需要更多代码或解释,请告诉我,我会尽力提供帮助。

感谢您抽出宝贵时间阅读本文。

【问题讨论】:

  • close(pStatement) 是做什么的?
  • 它调用了 close 函数,它本身基本上只是pStatement.close(),但它只是让它看起来更漂亮一些,因为我关闭了许多语句和所有语句。
  • 你正在使用try-with-resources,所以你不应该自己close
  • 是的。虽然之前;即使没有try-with-resources,当我尝试在结果集上使用if 逻辑时,它仍然会关闭。有没有合适的方法来做到这一点?
  • 不知道你的异常堆栈跟踪是什么样的,我只能猜测。考虑使用 DBCP 进行连接并每次关闭它。

标签: java sql sqlite resultset sqlexception


【解决方案1】:

所以在谷歌搜索和睡觉之后,这对我有用。

compareDatabase中的搜索功能改为:

private Boolean search (String searchValue, Connection connection) {
    PreparedStatement ps = null;
    try {
        ps = connection.prepareStatement("SELECT * FROM lotdatabase where " +
                "(Vehicle) = (?)");
        ps.setString(1, searchValue);

        ResultSet resultSet = ps.executeQuery();

        //The following if statement checks if the ResultSet is empty.
        if (!resultSet.next()){
            resultSet.close();
            ps.close();
            return false;
        }else{
            resultSet.close();
            ps.close();
            return true;
        }

    } catch (SQLException e) {
        e.printStackTrace();
    }
    return false;
}

compareDatabase 中的另一个函数中,我这样调用search 函数:

if (search(tempDataPoint, connection)) {
      System.out.println("MATCH FOUND: " + tempDataPoint);
}else {
      System.out.println("NOT FOUND: " + tempDataPoint);
}

这使我可以检查ResultSet 并确保它已关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多