Java 在方法之间重用PreparedStatement?

Java 在方法之间重用PreparedStatement?,java,performance,architecture,jdbc,prepared-statement,Java,Performance,Architecture,Jdbc,Prepared Statement,我们都希望重用JDBCPreparedStatement,而不是在循环中创建新实例 但是如何处理不同方法调用之间的PreparedStatement重用? 重用-“规则”仍然有效吗 我是否应该考虑使用一个字段用于 PraveReDebug < /C>?还是应该在每次调用中关闭并重新创建准备好的语句(保持它本地)? (当然,此类类的实例将绑定到连接,这在某些体系结构中可能是一个缺点) 我知道理想的答案可能是“视情况而定”。 但我正在寻找一个经验较少的开发人员的最佳实践,他们在大多数情况下都会做出正

我们都希望重用JDBC
PreparedStatement
,而不是在循环中创建新实例

但是如何处理不同方法调用之间的
PreparedStatement
重用? 重用-“规则”仍然有效吗

我是否应该考虑使用一个字段用于<代码> PraveReDebug < /C>?还是应该在每次调用中关闭并重新创建准备好的语句(保持它本地)? (当然,此类类的实例将绑定到

连接
,这在某些体系结构中可能是一个缺点)

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

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

可能是吧?这将是一个巨大的劣势。您要么需要同步对它的访问,这将使您的多用户性能一蹶不振,要么创建多个实例并将它们保存在一个池中。屁股痛得厉害

语句池是JDBC驱动程序的工作,当前的大部分(如果不是全部的话)驱动程序都为您完成了这项工作。调用
prepareStatement
prepareCall
时,驱动程序将处理现有资源和预编译语句的重复使用

语句
对象绑定到连接,应使用连接并尽快返回到池中


简言之,在方法开始时获取
PreparedStatement
,在循环中重复使用它,然后在方法结束时关闭它的标准实践是最佳实践。

是的,它可以重复使用,但我相信,只有在使用相同的
连接
对象,并且使用数据库连接池(例如,从Web应用程序中)时,这才算数,那么
连接
对象每次都可能不同

因此,每次在Web应用程序中使用前,我都会重新创建
PreparedStatement


如果你没有使用连接池,那么你就是黄金

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

许多数据库工作负载是CPU绑定的,而不是IO绑定的。这意味着,与访问磁盘相比,数据库最终将花费更多的时间来执行诸如解析SQL查询和找出如何处理它们(执行“执行计划”)之类的工作。与“报告”工作负载相比,“事务”工作负载的情况更为如此,但在这两种情况下,准备计划所花费的时间都可能超出您的预期

因此,如果语句要频繁执行,并且在“方法调用之间”进行(正确)安排缓存PreparedStatements的麻烦值得开发人员花费时间,那么这总是一个好主意。与性能一样,度量是关键,但如果您能够以足够低的成本进行度量,请出于习惯而缓存您准备好的语句


一些JDBC驱动程序和/或连接池提供了透明的“预处理语句缓存”,因此您不必自己进行缓存。只要您了解您选择的特定透明缓存策略的行为,就可以让它跟踪事情。。。您真正想要避免的是对数据库的攻击。

绝对不要将其作为类的字段。保持它的本地性。有很多健全的查询需要大量的IO在数据库上。具体地说,任何进行计算/聚合的东西。。。关于大型数据集。@Jochaim Sauer:我已经对我的鲁莽断言进行了限定:-)我不明白为什么这是一件大事。每个连接有一个线程。每个服务类(包含CRUD方法)预先构造PreparedStatements,并跨所有方法重用它们。连接关闭时PreparedStatements将关闭。由于PreparedStatements“属于”特定连接,因此无法在不同连接之间重用它。当然,您可以重用一些将沿不同连接执行的代码,但PreparedStation的好处是让它只准备一次,然后重用它,这在使用不同的连接时是不可能的。