JDBC - 语句、PreparedStatement、CallableStatement 和缓存

Posted

技术标签:

【中文标题】JDBC - 语句、PreparedStatement、CallableStatement 和缓存【英文标题】:JDBC - Statement, PreparedStatement, CallableStatement and caching 【发布时间】:2012-01-12 08:26:18 【问题描述】:

我想知道 StatementPreparedStatementCallableStatement 有什么区别以及何时使用。

使用这些方法的最佳实践和典型场景是什么?

【问题讨论】:

【参考方案1】:

语句与 PreparedStatement

    使用 PreparedStatement 可以提高性能,但取决于数据库。

    使用 PreparedStatement 可以避免 SQL 注入。 How does a PreparedStatement avoid or prevent SQL injection?

    通过 setInt、setString 使用preparedStatement 进行更好的类型检查,其中作为语句,您只需继续附加到主SQL。

类似的帖子:

Difference between Statement and PreparedStatement

CallableStatement - 跨所有数据库访问 StoredProcedures 的 Java 答案。

类似的帖子

CallableStatement vs Statement

使用 PreparedStatement 和 Callable 你已经有了缓存,缓存本身也是一个很大的话题,你不想做所有这些,而是​​看ehcache

你应该总是更喜欢 PreparedStatement 而不是 Statement

如果您必须对 StoredProcedure 进行操作,则只有一个选项 CallableStatement。

【讨论】:

“有了 PreparedStatement 和 Callable,你已经有了缓存”。是这样吗?据我所知,缓存仅适用于 SQL 执行计划。这些结构不会缓存查询结果。【参考方案2】:

我建议您在传递参数的任何时候都使用 PreparedStatement,无论您是否会重新使用该语句。在实践中,我将 PreparedStatement 用于除过程调用之外的所有内容,并让 DB 和 JDBC 驱动程序决定缓存什么以及如何缓存。过程调用应该使用 CallableStatement 来处理缺乏一致的跨数据库过程调用语法。

在 PostgreSQL 上,JDBC 驱动程序会在客户端缓存准备好的语句,直到达到特定的重用阈值。此时会发出服务器端 PREPARE 并且未来的执行将使用服务器端准备好的语句及其缓存计划。由于 PostgreSQL 的基于统计的查询计划器,这可能会产生一些……有趣的……和意想不到的效果。如果您的表具有某些值分布(或由于缺少 ANALYZE、错误的 random_page_cost 或太低的统计阈值而导致的错误统计信息),则计划程序可能会选择一个不同且较慢的查询计划,当它有一个未知参数时它会选择如果它知道您正在搜索的实际值。如果您在第 5 次(默认情况下)重复特定语句后遇到查询突然大幅减速,您可能会被这个问题困扰,并且可以通过 PgJDBC 中的turning off server-side PREPARE 解决它。通过检查特定参数是否具有与未知值案例非常不同的统计信息,正在检测服务器中的这些问题案例,但 AFAIK 它尚未命中 HEAD。另见this question。搜索 pgsql-general 邮件列表和 *** 了解更多信息。

【讨论】:

以上是关于JDBC - 语句、PreparedStatement、CallableStatement 和缓存的主要内容,如果未能解决你的问题,请参考以下文章

JDBC连接数据库(Java DataBase Connectivity,java)

DBeaver客户端工具结果集缓存实现的猜测

java连接SQL Server数据库

SQL DATE 与 java.sql.Date 中的时区

JDBC:无法创建语句

在JDBC中实现SQL语句的模糊查询