一、一级缓存
1、在session上面有一个一级缓存,一级缓存的生命周期和session相同,一级缓存最大生命周期就是一个线程;在web环境下面,session的最大生命周期就是一次请求;
2、两个Session不能共享一级缓存,因为会伴随session的生命周期的创建和销毁
3、一级缓存可以用来干什么
- 只能有限的提高一点点系统性能
- 最重要的功能:提供给了一个临时存放持久化对象的空间;
4、一级缓存相关的方法
- session.clear():清除一级缓存中所有的对象
- boolean contains(Object obj):判断一级缓存中是否有给定的对象
- session.evict(Object obj):从一级缓存中清除指定的对象
- session.flush():把一级缓存中的脏数据同步到数据库中
- session.refresh(Object obj):强制重新查询对象,相当于把数据库中的数据同步到一级缓存中。
二、二级缓存
在更多的情况下,我们要提高的性能的数据往往是不同请求,请求的相同数据;这样就需要二级缓存
1、二级缓存概念:
1.1:生命周期为整个应用的缓存(二级缓存是sessionFactory上的缓存,能提供整个应用中所有的session使用,可以在不同的请求之间共享缓存的数据)
1.2:所有的get,load方法,总是先查一级缓存,再查二级缓存,如果都没有,再去数据库里面查询。
1.3:不是所有的对象都适合放到二级缓存中,适合放入二级缓存中的情况
- 1.3.1:经常查询的数据
- 1.3.2:很少被修改的数据
- 1.3.3:不会被并发访问的数据
- 1.3.4:经常被修改的数据是不适合二级缓存的
1.4:二级缓存有一些性能的指标
- 1.4.1:命中率(总的从二级缓存中取得的数量/总的取的数量)
- 1.4.2:最大对象数量
- 1.4.3:最大空闲时间
- 1.4.4:移除数据策略;FIFO FILO LRU
1.5:二级缓存实际上就是一个缓存,所以,hibernate并没有实现自己的二级缓存框架,而是用的开源的。
cache.png1.6:二级缓存的原理
二级缓存其实就是个缓存.什么是缓存?其实简单理解就是一个Map;
既然二级缓存是一个Map;就会有相关的操作;
往二级缓存中添加一个对象;--->session保存一个对象,查询:get/load/query的实体对象
从二级缓存中删除一个对象;-->session.delete
修改二级缓存中的对象;-->session.update
1,调用session.update方法的时候,删除二级缓存中的这个对象;
2,直接替换掉二级缓存中对应的对象;
2、EHCache的配置和应用
1、准备工作
1.1、导入对应的二级缓存jar包(hibernate-release-5.1.17.Final / lib / optional / ehcache)
- ehcache-2.10.1.jar
- hibernate-ehcache-5.1.17.Final.jar
- slf4j-api-1.7.7.jar
1.2、在hibernate.properties里面配置属性
缺省情况下,是打开二级缓存的
hibernate.cache.use_second_level_cache=true
1.3、在hibernate.properties里面配置二级缓存的提供商
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
1.4、配置哪些对象需要放到二级缓存中
- 方式一:在hibernate.cfg.xml中(推荐)
<class-cache class="com.revanwang.common.Employee" usage="read-only"/>
- 方式二:在映射文件中添加,domain.hbm.xml
<cache usage="read-only"/>
2、具体配置
2.1、对象缓存策略
- 2.1.1:usage="read-only" :放到二级缓存里面的对象是只读(性能最高)
- 2.1.2:usage="read-write":允许读写(对并发支持较好)
- 2.1.3:usage="nonstrict-read-write":允许读写,但是在并发事务情况下会产生脏数据
- 2.1.4:usage="transactional" :允许读写,并且支持全事务(只能在ApplicationServer环境下有用)
2.2、ehcache.xml配置:
<defaultCache>:默认的cache,相当于公用cache;
<cache>:自定义的cache;
共同的配置:
- 1、maxElementsInMemory:该缓存池放在内存中最大的缓存对象个数;
- 2、eternal:是否永久有效,如果设置为true,内存中对象永不过期;
- 3、timeToIdleSeconds:缓存对象最大空闲时间,单位:秒;
- 4、timeToLiveSeconds:缓存对象最大生存时间,单位:秒;
- 5、overflowToDisk:当内存中对象超过最大值,是否临时保存到磁盘;
- 6、maxElementsOnDisk:能保存到磁盘上最大对象数量;
- 7、diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
- 8、memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
- 9、默认策略是LRU(最近最少使用),可以设置为FIFO(先进先出)或是LFU(较少使用)
3、自定义存储区域
- 默认情况下,所有的对象都是缓存在ehcache的defaultCache中;
- 一定注意,dafaultCache,eternal不能设置为true
- 把一个类放在指定的二级缓存区域中(可以细粒度的管理二级缓存的性能);
把一个类放在指定的二级缓存区域中(可以细粒度的管理二级缓存的性能)
- 0、给一个类添加region属性(二级缓存区块的名称)
<class-cache class="com.revanwang.common.Employee" usage="read-only" region="EMPLOYEE"/>
- 1、设置二级缓存区域前缀()
hibernate.cache.region_prefix=hibernateCache
- 2、设置哪些对象需要自定义缓存区域
<class-cache class="com.revanwang.common.Employee" usage="read-only" region="EMPLOYEE"/>
- 3、在ehcache.xml中配置一个cache名字 ehcache.xml.png
3、二级缓存相关操作
- 1)得到二级缓存对象
Cache cache=SessionFactory对象.getCache();
- 2):剔除一个实例
cache.evictEntity(Employee.class, 1L);
- 3):剔除某种类型的所有实例
cache.evictEntityRegion(Employee.class);
- 4):剔除所有二级缓存实例
cache.evictEntityRegions();
cacheOption.png
三、查询缓存
1、查询缓存实现原理
一级缓存和二级缓存都是对实体对象进行缓存,而查询缓存是针对于实体对象的属性.
开发中一般不使用查询缓存,可能会降低系统性能.
1.1:使用查询缓存的前提
- 1> HQL不能变;
- 2> 查询参数不能变;
- 3> 查询缓存结果类型中,如果有其他的事务(线程)更新过相同的类型,那么所有关于这个类型的查询缓存全部失效。
1.2:查询缓存执行流程:
- 1> 缓存HQL和对应的参数值;
- 2> 把查询结果对应的对象id序列保存到查询缓存中;
- 3> 遍历缓存,去加载每一个对象;
2、使用查询缓存
- 1,默认情况查询缓存关闭,手动开启设置
hibernate.cache.use_query_cache=true
- 2,在查询的时候
setCacheable(true)
useCache.png
网友评论