“Hibernate总是使用PreparedStatement来调用数据库”Quoted here。 如果是这样,那么hibernate缓存编译查询的位置,DB驱动程序是否会缓存它们。
我读到了关于c3p0的内容。如果hibernate默认缓存PreparedStatement,那么c3p0中hibernate.c3p0.max_statements的用途是什么。 如果hibernate默认不这样做,那么连接池必须用于缓存预准备语句。
请有人澄清这些。
答案 0 :(得分:11)
缓存预准备语句仅在特定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池实例(我很确定是自动为你创建的),这个配置与open open准备的事实有关语句受限于“物理”JDBC连接。