【问题标题】:Apply Try with Resources correctly in Java 7?在 Java 7 中正确应用 Try with Resources?
【发布时间】:2021-08-03 07:49:50
【问题描述】:

我正在使用 Java 7 开发一个使用 Angular 和 Spring 的应用程序,但是,我被要求使用 SonarQube 扫描我的代码,所以这个工具告诉我,我需要尝试使用资源来关闭我的 Prepared声明结果集,所以我做了一些研究,我是这样实现的:

try (Connection connection = DriverManager.getConnection(connectionUrl);
            Statement statement = connection.createStatement();
            PreparedStatement sentence = connection.prepareStatement(selectSql);
            ResultSet resultSet = sentence.executeQuery();) {
    

        // Create and execute a SELECT SQL statement.
        sentence.setString(1, parametro);
        logger.info(resultSet + " resultSet!----------------------------------------");

        // Print results from select statement
        while (resultSet.next()) {
            logger.info(" Entro al While!----------------------------------------");
            euroList.add(new EuroModel(resultSet.getInt("ID"), resultSet.getString("RFC"),
                    resultSet.getString("NOM")));
            logger.info("recibiendo result-> " + resultSet.getString(2) + " " + resultSet.getString(3));
            logger.info(euroList.toString());

        }

    } catch (SQLException e) {
        logger.info("No se pudo conectar");
        logger.info("EuroService");
        logger.info("INFO: " + e);
        List<EuroModel> empty = null;
        return empty;
    }

但是,由于以下行位于错误的位置,我的代码无法正常工作,我不知道应该在哪里尝试使用资源:

sentence.setString(1, parametro);

有人可以帮帮我吗?

【问题讨论】:

    标签: java sql-server spring sonarqube try-catch


    【解决方案1】:

    在设置 PreparedStatement 的参数之前,您正在执行查询。

    您可以从 try-with-resources 中删除 ResultSet,因为 it will be closed automatically:

    ResultSet 对象在生成它的 Statement 对象关闭、重新执行或用于从多个结果序列中检索下一个结果时自动关闭。

    您要确保在设置参数后执行 PreparedStatement 的查询,并获取相应的 ResultSet:

    try (Connection connection = DriverManager.getConnection(connectionUrl);
            Statement statement = connection.createStatement();
            PreparedStatement sentence = connection.prepareStatement(selectSql)) {
    
    
        // Create and execute a SELECT SQL statement.
        sentence.setString(1, parametro);
        ResultSet resultSet = sentence.executeQuery();
        logger.info(resultSet + " resultSet!----------------------------------------");
    

    更新

    从中吸取的一个有用的额外教训:SonarQube 在良好的编程实践方面并不是权威。事实上,SonarQube 在半常规的基础上是错误的。

    就是这种情况。 Sonar 不够聪明,无法知道 ResultSet 在其父 Statement 关闭时会自动关闭。 Sonar 只知道有一个可关闭的对象,它似乎没有在代码中显式关闭。

    正如 Slaw 所建议的,您可以通过对 ResultSet 使用另一个 try-with-resources 来让 Sonar 满意:

    try (Connection connection = DriverManager.getConnection(connectionUrl);
            Statement statement = connection.createStatement();
            PreparedStatement sentence = connection.prepareStatement(selectSql)) {
    
    
        // Create and execute a SELECT SQL statement.
        sentence.setString(1, parametro);
        try (ResultSet resultSet = sentence.executeQuery()) {
            logger.info(resultSet + " resultSet!----------------------------------------");
    
            while (resultSet.next()) {
                // etc.
            }
        }
    

    【讨论】:

    • 是的,但如果我这样做,SonarQube 会将 ResultSet 标记为漏洞,因为不会根据它关闭。所以我需要让我的代码工作并从 SonarQube 获得及格分数。
    • @ErickFinn 然后,如果你真的需要,你可以在已有的语句中嵌套另一个 try-with-resources 语句。
    • @ErickFinn 更新了答案。
    • @VGR 我知道,但我的老板不这么看。无论如何,该应用都必须通过 SonarQube。
    猜你喜欢
    • 2013-07-13
    • 2013-06-30
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多