2017-02-01 50 views
4

我正在研究一个继承的大型Java代码库,其中许多不同的方法以疯狂不同的方式对数据库进行查询;因为我一直在调试,规范一切,最让我写的代码最终看起来像这样:从实用程序方法返回PreparedStatement是否是一种好习惯?

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中准备PreparedStatement的方法是好的还是不好的做法(与处理ResultSet对象相反,如线程Is it Ok to Pass ResultSet?)。

为什么我预期的PreparedStatement预备好是一个坏主意?

+1

您可能想要检查[DbUtils](https://commons.apache.org/proper/commons-dbutils/),[jdbc-helper](https://code.google.com/archive/) p/jdbc-helper /)或[jdbi](http://jdbi.org/)。他们完成您在问题中展示的所有工作,并且在您不需要/需要整个ORM系统(如Hibernate,MyBatis,jooq等)时使用它们很好用。(编辑:修正了jdbc-helper链接到我正在考虑的那个,而不是Jruby的那个) –

回答

2

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

在这里看到更多的信息:Reusing of a PreparedStatement between methods?

+2

我不认为OP正在讨论重复使用声明。 – CKing

+0

是的,但问题在于谈论您不再拥有本地方法的PreparedStatement的场景。它在一个地方创建并传递给另一个方法。这是我的担忧。 – sharath

3

这样做是一个很好的一个极好的主意

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

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

您特别提到的情况也可能依赖于您使用的数据库层,因为某些DB期望输入像空列表或某些不同的值,或者只是null(Oracle,我在看着你!)。所以我强烈鼓励使用这些库,而不是编写我自己的实用工具方法,jDBI是我的首选,因为它是目前正在积极开发中的方法。

相关问题