java - hibernate是否默认使用PreparedStatement

标签 java performance hibernate jakarta-ee

“Hibernate 总是使用 PreparedStatement 来调用数据库”引用 here . 如果是这样,那么 hibernate 在哪里缓存编译的查询,数据库驱动程序是否缓存它们。

我阅读了有关 c3p0 的信息。如果hibernate默认缓存PreparedStatement那么c3p0中的hibernate.c3p0.max_statements有什么用。 如果 hibernate 默认不这样做,那么连接池对于缓存准备好的语句是强制性的。

有人可以澄清这些吗。

最佳答案

缓存准备好的语句只在特定的 JDBC 连接范围内才有意义。因此,只有当 ORM 层可以使用某种连接池时,您才能从缓存准备好的语句中获益。否则,每次创建 Hibernate Session 时都会获得一个新的“物理”JDBC 连接(通常效率不高)。没有任何连接池缓存准备好的语句仅在单个 JDBC 连接/Hibernate Session 范围内有用。发生这种情况是因为没有任何连接池,“物理”连接实际上已关闭并且不会被重用 - 相反,只要需要,总是会使用数据库驱动程序创建一个新连接。

您需要考虑的另一件事是,单个 JDBC 连接上打开的准备好的语句的数量是有限的(据我所知,该限制取决于供应商并且因驱动程序实现而异)。因此,在池连接场景中,池实现可能需要知道在池的每个“物理”底层 JDBC 连接上可以维护多少打开的准备好的语句。可能会实现“最少使用的准备好的语句首先关闭”策略,但这纯粹是我的猜测。

我希望这是有道理的。每当我提到“物理”JDBC 连接时,我指的是与数据库的实际新 TCP/IP 连接。连接池获得的连接通常会装饰/包装一个“物理”连接。

编辑以更直接地回答您的问题:

Hibernate 最有可能使用和缓存 PreparedStatements(这是非常基本的 JDBC 优化)。问题是这种缓存是否发生在由“物理”或池提供的 JDBC 连接创建的语句上。如果没有缓存池,PreparedStatements 只会优化在特定 Hibernate Session 范围内两次使用特定 PreparedStatement 的应用程序执行部分。对于池,相同的 PreparedStatement 将(有效地)用于许多 Hibernate Session 实例,这些实例恰好使用相同的底层“物理”连接。

你的 hibernate 配置的属性 hibernate.c3p0.max_statements 很可能会配置 C3PO 池实例(我很确定它是自动为你创建的)并且这个配置与打开准备的数量有关语句被限制在“物理”JDBC 连接中。

关于java - hibernate是否默认使用PreparedStatement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17764142/

相关文章:

c# - 我是否应该在实现INotifyPropertyChanged的大量对象上遇到性能问题?

java - Hibernate基础程序中的org.hibernate.HibernateException

java - Spring + Hibernate4 + JTA + JBossTS

java - Elasticsearch |模板查询 | Java接口(interface)

java - 为什么 MongoDB Java API 的更新插入如此慢?

MySQL WHERE 子句查询优化

java - 选择后的 Spring MVC 细化下拉列表

java - 如何使用for循环输入10个数字并只打印正数?

java - 启用ZGC时获取 'allocation stall'

c++ - 自定义语言中 C++ 的 C-Wrapper DLL 的性能