在 Java 7 中正确应用 Try with Resources?
Apply Try with Resources correctly in Java 7?
我正在使用 Angular 和 Spring 以及 Java 7 开发一个应用程序,但是,我被要求使用 SonarQube 扫描我的代码,所以这个工具告诉我我需要尝试使用资源来关闭我的 Prepared Statement 和 Result Set,所以我做了一些研究并像这样实现它:
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);
有人可以帮我吗?
您在设置 PreparedStatement 的参数之前正在执行查询。
您可以从 try-with-resources 中删除 ResultSet,因为 it will be closed automatically:
A ResultSet
object is automatically closed when the Statement
object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
你想确保执行你的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.
}
}
我正在使用 Angular 和 Spring 以及 Java 7 开发一个应用程序,但是,我被要求使用 SonarQube 扫描我的代码,所以这个工具告诉我我需要尝试使用资源来关闭我的 Prepared Statement 和 Result Set,所以我做了一些研究并像这样实现它:
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);
有人可以帮我吗?
您在设置 PreparedStatement 的参数之前正在执行查询。
您可以从 try-with-resources 中删除 ResultSet,因为 it will be closed automatically:
A
ResultSet
object is automatically closed when theStatement
object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
你想确保执行你的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.
}
}