我有一个函数,它使用动态数量的where
子句构建SQL查询。
SQL查询表达式存储在ResultSet中,我想在try with resource
中声明这个结果集。但是,这需要声明的元素来实现AutoCloseable
,而类型String
则不需要。
我的想法是使用lambda方法,将其作为executeQuery的参数传递,以便将其返回用作String参数,如下所示:
try (Statement s = getStatement();
String test = "test";
ResultSet rs = s.executeQuery(() -> {
String query = "build y query here";
return query;
});
)
但这会在executeQuery
上产生以下错误:
类型Statement中的方法executeQuery(String(不是适用于参数(((->{}(
以及() ->
:
此表达式的目标类型必须是功能接口
有办法实现我想要实现的目标吗?
executeQuery
接受一个字符串。它不需要Supplier<String>
或任何类似的东西。它要求急切地提供查询。最接近你建议的是:
Supplier<String> supplier = () -> {
String query = "build y query here";
return query;
};
ResultSet rs = s.executeQuery(supplier.get());
由于Statement
提供的签名限制了供应商的评估,因此这样做毫无价值。你不妨把它提取到一个方法中。
ResultSet rs = s.executeQuery(buildQuery());
// ...
String buildQuery() {
String query = "build y query here";
return query;
}
理论上,他们可以添加Supplier<String>
签名,这将允许Statement
将查询的构建推迟到最后可能的时刻。这可能比急切地构建它晚几毫秒。
我相信您可以使用try with resources作为结果集本身:
try (PreparedStatement ps = connection.prepareStatement(sql)) {
setupParams(ps, params);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
// process the row
}
}
}
一般来说,您可以使用spring的JDBC模板或JDBI 之类的库,而不是使用相当低级别的JDBC(因此很痛苦;(
如果您完全需要使用纯JDBC运行查询,请考虑阅读本文
它在这个方向上又前进了几步,并提出了非常有趣的解决方案