我们都know that我们应该重用JDBC PreparedStatement
而不是在循环中创建新实例。
但是如何处理不同方法调用之间的PreparedStatement
重用?
重用 - “规则”仍然有效吗?
我是否应该考虑为PreparedStatement
使用字段,还是应该在每次调用时关闭并重新创建预准备语句(保持本地)?
(当然,这样一个类的实例将绑定到Connection
,这在某些架构中可能是一个缺点)
我知道理想的答案可能是“它取决于” 但我正在寻找经验不足的开发人员的最佳实践,他们会在大多数情况下做出正确的选择。
答案 0 :(得分:13)
当然,这样一个类的实例将绑定到一个可能不利的连接
可能吗?这将是巨大的劣势。您需要同步对它的访问权限,这会导致您的多用户性能下降,或者创建多个实例并将它们保存在池中。屁股上的主要痛苦。
语句池是JDBC驱动程序的工作,大多数(如果不是全部)当前的驱动程序都会为您执行此操作。当您调用prepareStatement
或prepareCall
时,驱动程序将处理现有资源和预编译语句的重用。
Statement
个对象绑定到一个连接,应该使用连接并尽快返回到池中。
简而言之,标准做法是在方法开始时获取PreparedStatement
,在循环中重复使用它,然后在方法结束时关闭它, 最好实践。
答案 1 :(得分:6)
许多数据库工作负载受CPU限制,而不受IO限制。这意味着数据库最终花费更多时间来完成工作,例如解析SQL查询并找出如何处理它们(执行“执行计划”),而不是花费在访问磁盘上。 “交易”工作负载比“报告”工作负载更为正确,但在这两种情况下,准备计划所花费的时间可能比预期的要多。
因此,总是一个好主意,如果语句将要经常执行,并且在方法调用之间进行(正确)安排以缓存PreparedStatements的麻烦'值得您的开发人员时间。与性能一样,测量是关键,但如果你能够以足够低的成本做到这一点,请将您的PreparedStatement缓存出来。
某些JDBC驱动程序和/或连接池提供透明的“预准备语句缓存”,因此您无需自己执行此操作。只要您了解特定选择的透明缓存策略的行为,就可以让它跟踪事物......您真正想要避免的是数据库中的命中。
答案 2 :(得分:0)
是的,它可以重复使用,但我相信只有在使用相同的Connection
对象且您正在使用数据库连接池(例如,在Web应用程序中)时才会计算{} 1}}每次对象都可能有所不同。
出于这个原因,我总是在Web应用程序中每次使用之前重新创建Connection
。
如果您没有使用连接池,那么您就是金色的!
答案 3 :(得分:0)
我没有看到区别:如果我对同一个连接重复执行相同的语句,为什么不以任何方式重用PreparedStatement
?如果多个方法执行相同的语句,那么该语句可能需要封装在自己的方法中(甚至是它自己的类)。这样你就不需要传递PreparedStatement
。