hibernate是否默认使用PreparedStatement

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

我读到了关于c3p0的信息。 如果hibernate默认缓存PreparedStatement,那么c3p0中hibernate.c3p0.max_statements的用途是什么。 如果hibernate默认不这样做,那么连接池必须用于缓存预准备语句。

有人可以澄清这些。

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

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

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

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

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

你的hibernate配置的属性hibernate.c3p0.max_statements很可能会配置C3PO池实例(我很确定是自动为你创建的),这个配置与开放式预处理语句的数量有限有关。在“物理”JDBC连接中。