【发布时间】:2020-01-08 12:54:27
【问题描述】:
我环顾四周,但似乎找不到我的问题的答案。
这里是上下文:我必须在我的 Java 程序中连接到数据库并执行我无法控制且事先不知道的 SQL 请求。为此,我使用下面的代码。
public Collection<HashMap<String, String>> runQuery(String request, int maxRows) {
List<HashMap<String, String>> resultList = new ArrayList<>();
DataSource datasource = null;
try {
Context initContext = new InitialContext();
datasource = (DataSource) initContext.lookup("java:jboss/datasources/xxxxDS");
} catch (NamingException ex) {
// throw something.
}
try (Connection conn = datasource.getConnection();
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(request); ) {
while (rs.next())
{
HashMap<String, String> map = new HashMap<>();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
map.put(rs.getMetaData().getColumnName(i).toUpperCase(), rs.getString(i));
}
resultList.add(map);
}
} catch (SQLException ex) {
// throw something.
}
return resultList;
}
我面临的问题是: 如您所见,我不使用另一个参数maxRows。我需要将此指定给statement,但不能在try-with-resources 中执行。
我想通过在第一个方法中嵌套另一个try-with-resources 来避免增加这种方法的认知复杂性,以指定最大行数(就像在这个代码示例中一样)。
try (Connection conn = datasource.getConnection();
Statement statement = conn.createStatement(); ) {
statement.setMaxRows(maxRows);
try (ResultSet rs = statement.executeQuery(request); ) {
while (rs.next())
{
HashMap<String, String> map = new HashMap<>();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
map.put(rs.getMetaData().getColumnName(i).toUpperCase(), rs.getString(i));
}
resultList.add(map);
}
}
} catch (SQLException ex) {
// throw something.
}
有没有办法只用一个try-with-resources?
【问题讨论】:
-
您可以创建一个单独的方法来创建一个语句和
setMaxRows。类似于this 回答中的方法 -
您不必关闭 ResultSet。关闭一个 Statement 将自动关闭它的 ResultSet。来自the documentation:“当
Statement对象关闭时,其当前的ResultSet对象(如果存在)也将关闭。” -
@VGR 哦,我浏览文档时没有看到注释,感谢您指出!请注意,Sonar 不了解文档,如果您将其从
try中删除,您应该使用try-with-resources。 -
这就是为什么 Sonar 和任何其他代码分析工具都不应该被视为最佳实践的最终决定。
-
你说得对!
标签: java connection try-with-resources code-complexity