我怎么知道准备好的语句是否被缓存了?

时间:2019-05-24 15:24:49

标签: spring hibernate hikaricp

我在Tomcat lib文件夹中将Hikari与SQL Server 2016和sqljdbc4-2.0.jar一起使用。

我对数据库资源的配置如下:

cmd = 'powershell.exe try{get-ADComputer ' + hname + ' -Server 
' + server + ' | Out-Null}catch{}'

我的数据源配置如下:

subprocess.Popen('powershell.exe get-ADComputer ' + hname + ' 
-Server ' + sname + ' -Properties '
'OperatingSystem,PasswordLastSet | Export-CSV adcomputer.csv - 
Delimiter "*" -NoTypeInformation | Out-Null')

我如何知道preparestatement缓存是否适用于不同的连接?

我正在将Spring容器管理的事务与hibernate v4.3.10.Final一起使用。

此外,要使缓存起作用,是否需要启用二级缓存?

2 个答案:

答案 0 :(得分:3)

HikariCP实际上不支持PreparedStatement caching

  

其他人提供PreparedStatement缓存。 HikariCP没有。为什么?

这被认为是错误的实现

  

在池化层使用语句缓存是一种反模式,与驱动程序提供的缓存相比,会对应用程序性能产生负面影响。

说明:

  

在连接池层,PreparedStatements只能按每个连接进行缓存。如果您的应用程序有250个通常执行的查询和20个连接的池,则您要数据库保留5000个查询执行计划-同样,该池必须缓存这么多的PreparedStatement及其相关的对象图。

     

大多数主要的数据库JDBC驱动程序已经具有可以配置的Statement缓存,包括PostgreSQL,Oracle,Derby,MySQL,DB2和许多其他缓存。 JDBC驱动程序处于利用数据库特定功能的独特位置,几乎所有缓存实现都能够跨连接共享执行计划。这意味着您的250个经常执行的查询会在数据库中精确地产生250个执行计划,而不是在内存和相关的执行计划中存储5000条语句。聪明的实现甚至不会在驱动程序级别的内存中保留PreparedStatement对象,而只是将新实例附加到现有计划ID。

如果接受,则不应\期望缓存PreparedStatement

如果拒绝,则可以将C3P0用作连接池

关于Second level cache in hibernate,它通常没有在连接池中定义,但是使用相关的连接提供程序:

  

HikariCP现在具有用于Hibernate 4.x的ConnectionProvider,称为HikariConnectionProvider

     

为了在Hibernate 4.x中使用HikariConnectionProvider,请将以下属性添加到hibernate.properties配置文件中:

hibernate.connection.provider_class=com.zaxxer.hikari.hibernate.HikariConnectionProvider
     

从Hibernate 4.3.6开始,有一个来自Hibernate的官方ConnectionProvider类,应使用它代替HikariCP实现。该类称为org.hibernate.hikaricp.internal.HikariCPConnectionProvider

答案 1 :(得分:0)

对于任何需要Oracle JDBC的人, 引用link

尽管Oracle JDBC驱动程序在设计时就启用了隐式缓存,但默认情况下未启用此功能。要在连接上启用隐式缓存,可以将相应的OracleConnection对象的hiddenCachingEnabled属性设置为true,并将statementCacheSize属性设置为正整数

要在连接池上启用它,我们需要

connectionPoolObject.setMaxStatements(10);

如果执行此操作,将为池中的每个连接

启用语句缓存

要验证是否启用了缓存,

  if (conn.getImplicitCachingEnabled())
       System.out.println("\nimplicit caching enabled");
  else
       System.out.println("\nimplicit caching disabled"); 

我们甚至可以在语句级别进行验证,

//Checking the creation state of the prepared statement
int creationState = stmt.creationState();
switch(creationState) {
 case 0:
 System.out.println("\nCreation state: new");
 break;
case 1:
 System.out.println("\nCreation state: from the implicit cache"); 
 break;
case 2:
 System.out.println("\nCreation state: from the explicit cache"); 
 break;
}

第一次在连接C1上执行该语句时,情况1为真;如果在同一连接C1上再次执行同一语句,则情况2为真。