缓存是一种增强系统性能的机制.它是应用程序和数据库之间的缓冲区内存.高速缓存存储器存储最近使用的数据项,以尽可能减少数据库命中数.
高速缓存对Hibernate也很重要.它使用多级缓存方案,如下所述 :
第一级缓存是会话缓存,是所有请求必须通过的强制缓存.在将对象提交到数据库之前,Session对象保持一个对象.
如果对对象发出多个更新,Hibernate会尽可能地延迟执行更新以减少发出的更新SQL语句的数量.如果关闭会话,则缓存的所有对象都将丢失,并在数据库中保留或更新.
二级cache是一个可选的缓存,在尝试在二级缓存中定位对象之前,将始终查询第一级缓存.可以基于每个类和每个集合配置二级缓存,主要负责跨会话缓存对象.
任何第三方缓存都可以与Hibernate一起使用.提供了一个 org.hibernate.cache.CacheProvider 接口,必须实现该接口才能为Hibernate提供缓存实现的句柄.
Hibernate还为查询结果集实现了一个缓存,它与二级缓存紧密集成.
这是一个可选功能,需要两个额外的物理缓存保存缓存查询结果的区域以及上次更新表时的时间戳.这仅适用于使用相同参数频繁运行的查询.
Hibernate默认使用一级缓存你无关使用第一级缓存.让我们直接进入可选的二级缓存.并非所有类都受益于缓存,因此能够禁用二级缓存非常重要.
Hibernate二级缓存分两步设置.首先,您必须决定使用哪种并发策略.之后,使用缓存提供程序配置缓存过期和物理缓存属性.
并发策略是一个中介,负责用于在高速缓存中存储数据项并从高速缓存中检索它们.如果要启用二级缓存,则必须为每个持久化类和集合决定使用哪种缓存并发策略.
交易 : 在罕见的更新情况下,将此策略用于读取主要数据,以防止并发事务中的陈旧数据.
读取-write : 再次将此策略用于读取主要数据,其中在极少数情况下,在并发事务中防止陈旧数据至关重要.
Nonstrict-read-write : 此策略不保证缓存和数据库之间的一致性.如果数据几乎没有变化且过时数据的可能性很小,则使用此策略.
只读&减号;适用于数据的并发策略,永不改变.仅用于参考数据.
如果我们要为我们的员工使用二级缓存class,让我们添加告诉Hibernate使用读写策略缓存Employee实例所需的映射元素.
<?xml version = "1.0" encoding = "utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name = "Employee" table = "EMPLOYEE"> <meta attribute = "class-description"> This class contains the employee detail. </meta> <cache usage = "read-write"/> <id name = "id" type = "int" column = "id"> <generator class="native"/> </id> <property name = "firstName" column = "first_name" type = "string"/> <property name = "lastName" column = "last_name" type = "string"/> <property name = "salary" column = "salary" type = "int"/> </class> </hibernate-mapping>
usage ="read-write"属性告诉Hibernate对定义的缓存使用读写并发策略.
在考虑并发策略之后,您将使用缓存候选类来选择缓存提供程序. Hibernate强制您为整个应用程序选择一个缓存提供程序.
Sr.No. | 缓存名称&描述 |
---|---|
1 | EHCache 它可以缓存在内存或磁盘和群集缓存中,它支持可选的Hibernate查询结果缓存. |
2 | OSCache 支持使用一组丰富的过期策略和查询缓存支持在单个JVM中缓存到内存和磁盘. |
3 | warmCache 基于JGroups的集群缓存.它使用集群失效,但不支持Hibernate查询缓存. |
4 | JBoss Cache 完全事务复制的群集缓存也是基于JGroups组播库.它支持复制或失效,同步或异步通信以及乐观和悲观锁定.支持Hibernate查询缓存. |
每个缓存提供程序与每个缓存提供程序都不兼容并发策略.以下兼容性矩阵将帮助您选择合适的组合.
策略/提供者 | 只读 | 非严格 - 写 | 读写 | 交易 |
---|---|---|---|---|
EHCache | X | X | X | |
OSCache | X | X | X | |
SwarmCache | X | X | ||
JBoss Cache | X | X |
您将在hibernate.cfg.xml配置文件中指定缓存提供程序.我们选择EHCache作为我们的二级缓存提供商 :
<?xml version = "1.0" encoding = "utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name = "hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <property name = "hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- Assume students is the database name --> <property name = "hibernate.connection.url"> jdbc:mysql://localhost/test </property> <property name = "hibernate.connection.username"> root </property> <property name = "hibernate.connection.password"> root123 </property> <property name = "hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property> <!-- List of XML mapping files --> <mapping resource = "Employee.hbm.xml"/> </session-factory> </hibernate-configuration>
现在,您需要指定缓存区域的属性. EHCache有自己的配置文件 ehcache.xml ,它应该位于应用程序的CLASSPATH中.在ehcache.xml中,Employee类的缓存配置可能如下所示;
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory = "1000" eternal = "false" timeToIdleSeconds = "120" timeToLiveSeconds = "120" overflowToDisk = "true" /> <cache name = "Employee" maxElementsInMemory = "500" eternal = "true" timeToIdleSeconds = "0" timeToLiveSeconds = "0" overflowToDisk = "false" />
就是这样,现在我们为Employee类和Hibernate启用了二级缓存,现在每当你导航到一个Employee时就会点击二级缓存当您按标识符加载Employee时.
您应该分析所有类并为每个类选择适当的缓存策略.有时,二级缓存可能会降低应用程序的性能.因此,建议首先对应用程序进行基准测试,而不启用缓存,然后启用适合的缓存并检查性能.如果缓存没有提高系统性能,那么启用任何类型的缓存都没有意义.
要使用查询缓存,必须首先使用配置文件中的 hibernate.cache.use_query_cache ="true"属性将其激活.通过将此属性设置为true,可以使Hibernate在内存中创建必要的缓存来保存查询和标识符集.
接下来,要使用查询缓存,请使用setCacheable(Boolean) Query类的方法.例如 :
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); List users = query.list(); SessionFactory.closeSession();
Hibernate还通过缓存区域的概念支持非常细粒度的缓存支持.缓存区域是给定名称的缓存的一部分.
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); query.setCacheRegion("employee"); List users = query.list(); SessionFactory.closeSession();
此代码使用该方法告诉Hibernate在缓存的员工区域中存储和查找查询.