从实用程序方法返回PreparedStatement是一个好习惯吗?

时间:2017-02-01 14:38:01

标签: java

我正在开发一个继承的大型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()) - 这是进行维护时未来错误的一个方法。我宁愿把所有内容放在一个(静态的)通用方法中,这样我就可以只说一次(加上面向未来的代码库,以防需要其他一些操作...比如说,法律部门需要不同类型的日志记录,或要求进行新的错误处理)。像这样:

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准备工作是个坏主意?

2 个答案:

答案 0 :(得分:3)

这样做是一个好的 一个优秀的想法。

为什么好?因为您将PrepareStatement创作集中在一个地方。您的同事可以更干净地阅读您的代码。如果有错误,它会被固定在一个地方而不是所有地方。

这是一个好主意,几个框架甚至可以在您的位置设计。我在评论中提到了DbUtilsjdbc-helperjDBI。其他人是jcabi-jdbc,或者是受欢迎的JOOQ。好吧,他们并非都完全活跃(jdbc-helper甚至可能已经死了),但他们仍然在生产项目中使用。

您具体提到的情况也可能依赖于您使用的数据库层,因为某些数据库需要输入一些不同的值,例如空列表或只是null(Oracle,我看着你! )。所以我强烈建议使用这些库而不是编写我自己的实用程序方法,jDBI是我的首选,因为它是目前正在积极开发的那个。

答案 1 :(得分:2)

由于PreparedStatement绑定到Connection对象,因此需要对其进行同步,以便跨多个方法进行访问,这将限制您的多用户性能。

有关详细信息,请参阅此处:Reusing of a PreparedStatement between methods?