我正在处理一个继承的大型 Java 代码库,其中许多不同的方法以非常不同的方式对数据库进行查询;由于我一直在调试和标准化所有内容,因此我编写的大部分代码最终看起来像这样:
log.info("Audit-required logging for query: "+SOME_QUERY);
log.info("Ditto for each argument: "+parameter+" "+otherParameter+ ...);
ps = conn.prepareStatement(SOME_QUERY);
ps.setString(1, aString);
ps.setString(2, anotherString);
// ...
ps.setString(14, yetAnotherString);
rs = ps.executeQuery();
log.debug("Query executed: "+SOME_QUERY);
我讨厌我必须写下三次查询和两次参数(加上为每个人写一个 setString())——这是在进行维护时 future 错误的一个秘诀。我宁愿把所有这些都放在一个(静态)通用方法中,这样我就可以把所有内容都说一遍(加上面向 future 的代码库,以防需要其他一些操作……比如,说一个不同的法律部门要求进行日志记录,或者要求进行新的错误处理)。像这样的东西:
public static PreparedStatement fullyPrepare(final Connection conn, final String query, final String... arguments) { ... }
然后我会用一个句子调用它(而不是每次都调用整个代码块):
ps = fullyPrepare(conn, CONSTANT_FOR_THIS_QUERY, parameter, otherParameter, ...);
然而,基于“这将是不好的做法”的想法,我发现了对此的抵制。我一直在尝试阅读有关此内容的信息,但是我找不到任何说明从准备它的方法返回 PreparedStatement 是好还是坏的做法(与处理 ResultSet 对象相反,就像在线程 Is it Ok to Pass ResultSet? 中一样)。
为什么我想要的 PreparedStatement 准备器是个坏主意?
最佳答案
这样做是一个很好的 一个很好的 想法。
为什么好?因为您将 PrepareStatement
创建集中在一个地方。您的同事可以更清晰地阅读您的代码。如果有错误,它会在一个地方修复,而不是无处不在。
这是一个好主意,甚至设计了几个框架来代替您这样做。我在评论中提到了 DbUtils 、 jdbc-helper 和 jDBI 。其他是 jcabi-jdbc ,或流行的 JOOQ 。好吧,它们并不是完全活跃(jdbc-helper 甚至可能已经死了),但它们仍在生产项目中使用。
您具体提到的情况也可能取决于您使用的数据库层,因为某些数据库期望输入有一些不同的值,例如空列表或简单的 null
(Oracle,我在看着您!)。所以我强烈鼓励使用这些库而不是编写我自己的实用程序方法,jDBI 是我的第一选择,因为它目前正在积极开发中。
关于java - 从实用程序方法返回 PreparedStatement 是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41982396/