【问题标题】:Use try-with-resources/close this "PreparedStatement" in a "finally" clause [duplicate]在“finally”子句中使用 try-with-resources/关闭此“PreparedStatement”[重复]
【发布时间】:2021-03-20 12:32:43
【问题描述】:

我在 sonarqube 上运行我的 JDBC 代码。我的代码有问题。

try (final Connection connection = DatabaseConnectionProvider.createConnection(configuration)) {
        PreparedStatement statement = connection.prepareStatement(
                "SELECT 1 FROM `todo_items` WHERE `id` = ? LIMIT 1;");
        statement.setLong(1, id);
        ResultSet resultSet = statement.executeQuery();
        if (!resultSet.next()) {
            return false;
        }
        statement = connection.prepareStatement("UPDATE `todo_items` SET `checked` = ? WHERE id = ?;");
        statement.setBoolean(1, checked);
        statement.setLong(2, id);
        statement.executeUpdate();
        return true;
    }

它在第 3 行和第 9 行显示存在阻塞问题。

“使用 try-with-resources 或在“finally”子句中关闭此“PreparedStatement”。”我不明白这个。

【问题讨论】:

  • 您已经有一个try-with-resource 用于连接。把准备好的语句也放在那里。
  • 如果你尝试 JdbcTemplate,你可以用更少的样板更简单地解决这个问题。您已经在使用 Spring。为什么你不使用那个类对我来说是个谜。您应该在启动时将数据源池化并在 Spring bean 工厂中实例化池。

标签: java spring jdbc


【解决方案1】:

您可以使用内部 try-with-resources,因为您在内部有 2 个不同的准备语句:

try (final Connection connection = DatabaseConnectionProvider.createConnection(configuration)) {
    try(PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM `todo_items` WHERE `id` = ? LIMIT 1;")) {
        statement.setLong(1, id);
        ResultSet resultSet = statement.executeQuery();
        if (!resultSet.next()) {
            return false;
        }
    }
    try(PreparedStatement statement = connection.prepareStatement("UPDATE `todo_items` SET `checked` = ? WHERE id = ?;")) {
        statement.setBoolean(1, checked);
        statement.setLong(2, id);
        statement.executeUpdate();
        return true;
    }
}

小优化是可能的(注意try(.....)中有2个Autoclosables:

try (final Connection connection = DatabaseConnectionProvider.createConnection(configuration);
        PreparedStatement statement = connection.prepareStatement("UPDATE `todo_items` SET `checked` = ? WHERE id = ?;")) {
    statement.setBoolean(1, checked);
    statement.setLong(2, id);
    return statement.executeUpdate() > 0;
}

您不必在 DB 中查询行是否存在,因为更新的行数通常由 executeUpdate() 返回。实际返回值可能取决于 JDBC 驱动程序实现(尽管 JDBC 规范对此非常清楚)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2021-12-09
    • 2019-03-31
    • 2021-12-14
    • 2020-05-13
    相关资源
    最近更新 更多