2011-01-10 62 views
6

我们都是knowthat我们应该重用JDBC PreparedStatement而不是在循环中创建一个新的实例。如何处理PreparedStatement不同的方法调用之间的重用? 重用 - “规则”是否仍然计数?在方法之间重用PreparedStatement?

我真的应该考虑使用PreparedStatement的字段,还是应该在每次调用时关闭并重新创建准备语句(保持本地状态)? (当然这样的类的实例将被绑定到Connection,这在某些体系结构中可能是缺点)

我知道理想的答案可能是“取决于”。
但是我正在寻找一个经验较少的开发者的最佳实践,他们会在大多数情况下做出正确的选择。

+3

绝对不要让它成为这个类的领域。保持本地化。 – BalusC 2011-01-10 13:59:39

回答

13

当然,这样的类的实例将被绑定到这可能是一个缺点

可能是有关联吗?这将是一个巨大的的劣势。你需要同步对它的访问,这会杀死你的多用户性能,或者创建多个实例并将它们保存在一个池中。在屁股的主要痛苦。

语句池是JDBC驱动程序的工作,并且大多数(如果不是全部的话)当前作物驱动程序会为您执行此操作。当您拨打prepareStatementprepareCall时,驱动程序将处理重新使用现有资源和预编译语句。

Statement对象绑定到一个连接,应该尽可能快地使用连接并返回到池中。

总之,在方法的开始获得PreparedStatement,反复使用它的环路内,则在该方法的结束时关闭它的标准做法,最佳实践。

+0

我不明白为什么这是一个大问题。每个连接有一个线程。每个服务类(包含您的CRUD方法)预先构建PreparedStatements,并在所有方法中重用它们。当连接关闭时,PreparedStatements会关闭。 – Gili 2011-01-19 00:53:00

0

是的,它可以重复使用,但我相信这只有在使用相同的Connection对象并且您正在使用数据库连接池(例如来自Web应用程序内部)时才会计数,那么Connection对象将有可能每次都不一样。

因为这个原因,在Web应用程序中每次使用之前我总是重新创建PreparedStatement

如果你不使用连接池,那么你是金!

0

我没有看到区别:如果我对同一个连接重复执行相同的语句,为什么不以任何方式重用PreparedStatement?如果多个方法执行相同的语句,那么可能该语句需要封装在自己的方法(甚至是它自己的类)中。这样你就不需要传递一个PreparedStatement

+1

由于PreparedStatement“属于”特定的连接,因此您不能在不同的连接中重复使用它。当然,您可以重用一些将在不同连接中执行的代码,但关于PreparedStatment的好处是只需将其准备好一次并重新使用即可,一旦您使用不同的Connection,这是不可能的。 – 2013-12-12 10:29:36

6

许多数据库工作负载受CPU限制,而不受IO限制。这意味着数据库最终会花费更多的时间进行工作,比如解析SQL查询并计算如何处理它们(执行'执行计划'),而不是花费在访问磁盘上。对于“事务性”工作负载而言,这比“报告”工作负载更为真实,但在这两种情况下,准备计划的时间可能超出您的预期。

因此,如果语句要经常执行,并且在方法调用之间缓存PreparedStatements的“正确”安排的麻烦值得您的开发人员时间,那么这总是一个好主意。与性能一样,衡量是关键,但如果您可以做到便宜,可以将PreparedStatement缓存在习惯之外。

某些JDBC驱动程序和/或连接池提供了透明的“准备好的语句缓存”,因此您不必亲自去做。只要您了解您选择的特定透明缓存策略的行为,就可以让它跟踪事情,这是很好的事情......您真正想要避免的是数据库上的命中。

+0

有很多理智的查询需要在数据库上提供大量的IO。具体而言,任何对大型数据集进行计算/聚合/ ...的任何事情。 – 2011-01-10 14:05:29