一、Hibernate的缓存机制
缓存cache是位于应用层与物理数据源之间临时存放复制数据的内存区域,其目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能。
Hibernate在查询数据时,首先会到缓存中查找,如果找到就直接使用,只有在缓存中找不到时才会从物理数据源中检索。因此,当把频繁使用的数据加载到缓存区后,就可以大大减少应用程序对物理数据源的访问,使应用程序性能提升。
二、缓存分类
在前面我们使用的Session缓存用于临时保存Session实例中的持久化对象,他是Hibernate不可分割的基本组成部分,因此被称为一级缓存。一级缓存可以使用用Session实例进行操做。
SessionFactory的外置缓存中存放的是数据库数据的副本,起作用与一级缓存类似,用于弥补一些缓存的不足,因此被称为二级缓存。二级缓存可以使用SessionFactory实例进行操作。在默认情况下,SessionFactory不会启用二级缓存,当需要的时候,可以将二级缓存以缓存插件的形式进行配置。
另外,二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。
三、二级缓存使用位置
不适合使用位置:
经常被修改的数据
出现并发访问的数据,如财务数据
与其他应用共享的数据,因为Hibernate并不能感知数据被其他应用的修改,也就是无法保证二级缓存中的数据与数据库中数据的一致性。
适合的使用位置
数据更新频率低,也就是那些很少被修改的数据。
允许偶尔出现并发问题的非重要数据。
不会被并发访问的数据
常量数据
不会被第三方修改的数据
四、使用配置方法:
1、在gradle中引入新包:compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final'
2、在resources中新建一个ehcache.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required: 缓存最大数目 maxElementsInMemory - sets the maximum number of objects that will be created in memory 缓存是否持久 eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. 是否保存到磁盘,当系统当机时 overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. The following attributes are optional: 当缓存闲置n秒后销毁 timeToIdleSeconds - Sets the time to idle for an element before it expires. i.e. The maximum amount of time between accesses before an element expires Is only used if the element is not eternal. Optional attribute. A value of 0 means that an Element can idle for infinity. The default value is 0. 当缓存存活n秒后销毁 timeToLiveSeconds - Sets the time to live for an element before it expires. i.e. The maximum time between creation time and when an element expires. Is only used if the element is not eternal. Optional attribute. A value of 0 means that and Element can live for infinity. The default value is 0. 指定缓存是否被持久化到硬盘中,保存路径由<diskStore>标签指定。 diskPersistent - Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value is 120 seconds. --> <ehcache> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="false"> </defaultCache> <cache name="org.hibernate.cache.internal.StandardQueryCache" maxElementsInMemory="5" eternal="false" timeToLiveSeconds="120"> </cache> <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxElementsInMemory="5000" eternal="true"> </cache> </ehcache>
上面是默认cache,如果默认cache不存在就走查询cache和修改cache。
3、在hibernate.cfg.xml配置文件中加载二级缓存
将一下配置信息加载property标签和mapping标签之间
<!-- 设置二级缓存插件EHCache的Provider类--> <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- 启用查询缓存,以缓存使用find(),list(),Iterator()等方法获得的查询结果集--> <property name="hibernate.cache.use_query_cache">true</property> <property name="hibernate.cache.provider_configuration_file_resource_path">classpath:ehcache.xml</property> <property name="hibernate.cache.use_second_level_cache">true</property>
4、在dao层的查询中使用二级缓存
public void query2(){ Session session=sf.openSession(); Father2 s=null; try { //Son2 s=session.load(Son2.class,6); Query q=session.createQuery("from Father2 as a "); q.setCacheable(true);//表示使用二级缓存 q.list(); Query q2 =session.createQuery("from Father2 where fid=1"); q2.setCacheable(true);//表示使用二级缓存 q2.list(); }catch(Exception e){ e.printStackTrace(); } session.close(); }