JDBC - Statement、PreparedStatement、CallableStatement和缓存

8
我想知道在何时使用StatementPreparedStatementCallableStatement这三个类并且它们有什么区别。
在何种情况下最好使用它们?每个类通常使用的场景是什么?
2个回答

7

Statement与PreparedStatement的区别

  1. PreparedStatement的性能更好,但是取决于数据库。

  2. 使用PreparedStatement可以避免SQL注入。 PreparedStatement如何避免或预防SQL注入?

  3. 通过setInt、setString等方法使用PreparedStatement可以进行更好的类型检查,而Statement只能将内容追加到主SQL中。

类似的帖子:

Statement和PreparedStatement的区别

CallableStatement - Java访问所有数据库存储过程的答案。

类似的帖子:

CallableStatement vs Statement

使用PreparedStatement和Callable已经具有缓存功能,缓存是一个独立的大主题,您不需要做所有这些工作,而是可以查看ehcache

几乎总是应该优先使用PreparedStatement而不是Statement

如果必须操作存储过程,则只有一种选择:CallableStatement。


1
“使用PreparedStatement和Callable,您已经具备了缓存功能。”是这样吗?据我所知,缓存仅适用于SQL执行计划。这些结构不会缓存查询结果。 - melihcelik

4

我建议在传递参数时几乎每次都使用PreparedStatement,无论您是否会重复使用该语句。实际上,除了过程调用之外,我在所有情况下都使用PreparedStatement,并让DB和JDBC驱动程序决定缓存和如何处理。过程调用应使用CallableStatement来处理缺少一致的跨数据库过程调用语法。

在PostgreSQL上,JDBC驱动程序会将准备好的语句缓存到客户端,直到达到一定的重用阈值。此时会发出服务器端PREPARE,并且未来的执行将使用服务器端准备好的语句及其缓存计划。由于PostgreSQL基于统计数据的查询规划器,这可能会产生一些有趣和意外的影响。如果您的表具有某些值分布(或由于缺乏ANALYZE、错误的random_page_cost或过低的统计阈值而导致错误的统计信息),当它具有未知参数时,规划器可能会选择不同且较慢的查询计划,而不是如果它已知道您正在搜索的实际值时所选择的计划。如果您在特定语句的第5次(默认情况下)重复之后遇到突然而大量的查询减速,则可能会受到此问题的影响,并且可以通过在PgJDBC中关闭服务器端PREPARE(链接1)来解决此问题。目前正在进行检测这些问题案例的工作,方法是检查特定参数是否与未知值情况下的统计信息非常不同,但据我所知,它尚未被应用到HEAD中。另请参见{{link2:此问题(链接2)}}。在pgsql-general邮件列表和stackOverflow上搜索更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接