【问题标题】:How to use try/catch with db statement and resultSet [duplicate]如何在 db 语句和 resultSet 中使用 try/catch [重复]
【发布时间】:2026-01-26 15:15:01
【问题描述】:
public SortedMap<String, TreeMap<String, String>> getCampo(String city, String sport, String 
    data) throws SQLException {
    TreeMap<String, TreeMap<String, String>> campoInfo = new TreeMap<>();
    
    
    Connection connection =null;
    Statement statement = null;
    ResultSet resultSet = null;
    
    try {
     connection = getConnection();
     statement = connection.createStatement();
    String query = String.format("SELECT * FROM CAMPO WHERE COMUNE='%s' AND SPORT='%s' AND DATA >= '%s' AND TORNEO = 0", city, sport, data);
     resultSet = statement.executeQuery(query);
    while (resultSet.next()) {
        String name = resultSet.getString("NOME");
        String id = "" + resultSet.getInt("ID");
        String comune = resultSet.getString("COMUNE");
        String indirizzo = resultSet.getString("INDIRIZZO");
        String desc = resultSet.getString("DESCRIZIONE");
        String renter = "" + resultSet.getInt("RENTER");
        String date = resultSet.getString("DATA");
        String ora = resultSet.getString("ORA");
        String metodo = resultSet.getString("METODODIPAGAMENTO");
        String prezzo = resultSet.getString("PREZZO");
        String isAffittabile = "" + resultSet.getString("AFFITTABILE");
        TreeMap<String, String> info = new TreeMap<>();
        info.put("ID", id);
        info.put("COMUNE", comune);
        info.put("INDIRIZZO", indirizzo);
        info.put("DESC", desc);
        info.put("RENTER", renter);
        info.put("DATA", date);
        info.put("ORA", ora);
        info.put("PREZZO", prezzo);
        info.put("METODODIPAGAMENTO", metodo);
        info.put("AFFITTABILE", isAffittabile);
        campoInfo.put(name, info);

    }
    
    
}
    catch (Exception e) {
        // TODO: handle exception
    }
   finally {
    if (resultSet!=null) {
        resultSet.close();
    }
    if (statement!=null) {
        statement.close();
    }
   }
    if (connection!=null){
       connection.close();}
    return campoInfo;
   }

我正在用 Java 和声纳扫描仪编写这个函数。我对变量“statement”和“resultSet”有疑问,因为当我尝试关闭它们时,在 finally 块中,Sonar 告诉我存在错误并使用 try-with 资源或在 finally 块中关闭它。它只发生在其中一个变量上,即块中的第二个。例如,首先我关闭了“resulSet”(没关系),但第二个没有关闭,Sonar 突出显示了它。我能做什么?

【问题讨论】:

  • 为什么不使用 try-with-resources 块(我认为这就是 SonarQube 所暗示的)。 try (Connection connection = getConnection() { try (Statement statement = connection.createStatement() { /* add your business logic */ } }最后会自动关闭
  • 你不觉得“connection.close();”是否在 finally 块中进行空检查?
  • 不,我不能在另一个尝试中使用一个尝试,Sonar 将其识别为代码气味。即使我添加了 'connection.close()' 错误也不会消失
  • @knittl 你甚至可以将它们组合成一个 try-with-resources

标签: java jdbc sonarqube


【解决方案1】:

您可以在 try() {} 块中初始化多个变量:

public SortedMap<String, TreeMap<String, String>> getCampo(String city, String sport, String data) throws SQLException {
    TreeMap<String, TreeMap<String, String>> campoInfo = new TreeMap<>();

    String query = String.format("SELECT * FROM CAMPO WHERE COMUNE='%s' AND SPORT='%s' AND DATA >= '%s' AND TORNEO = 0", city, sport, data);

    try (Connection connection = getConnection(); 
        Statement statement = connection.createStatement(); 
        ResultSet resultSet = statement.executeQuery(query)) {
        while (resultSet.next()) {
            String name = resultSet.getString("NOME");
            String id = "" + resultSet.getInt("ID");
            String comune = resultSet.getString("COMUNE");
            String indirizzo = resultSet.getString("INDIRIZZO");
            String desc = resultSet.getString("DESCRIZIONE");
            String renter = "" + resultSet.getInt("RENTER");
            String date = resultSet.getString("DATA");
            String ora = resultSet.getString("ORA");
            String metodo = resultSet.getString("METODODIPAGAMENTO");
            String prezzo = resultSet.getString("PREZZO");
            String isAffittabile = "" + resultSet.getString("AFFITTABILE");
            TreeMap<String, String> info = new TreeMap<>();
            info.put("ID", id);
            info.put("COMUNE", comune);
            info.put("INDIRIZZO", indirizzo);
            info.put("DESC", desc);
            info.put("RENTER", renter);
            info.put("DATA", date);
            info.put("ORA", ora);
            info.put("PREZZO", prezzo);
            info.put("METODODIPAGAMENTO", metodo);
            info.put("AFFITTABILE", isAffittabile);
            campoInfo.put(name, info);
        }

    } catch (Exception e) {
        // TODO: handle exception
    }
    return campoInfo;
}

我在这里看到的另一个问题是你真的应该使用准备好的语句(不是String.format)来构建查询

【讨论】:

  • 是的,但是我无法在 finally 块中访问它们,可能是因为 java 版本(1.8)。我知道不使用准备好的语句是完全不安全的,但是对于我需要的东西来说它更快。感谢警告
  • @PaulK “在 finally 块中无法联系到他们” 是什么意思?你不需要,这就是 try-with-resources 的用途。
  • 我的意思是,如果我尝试在 finally 块中执行“resultSet.close()”,eclipse 会告诉我“resultSet 变量无法解析”
  • 你不需要明确地关闭它,这就是 try-with-resources 块的意义所在。编译器会为您生成 close() 调用。