一级缓存:
session的缓存,当程序调用session接口的save(),upadte(),saveOrUpdate(),get(),load(),以及调用查询接口的list(),iterator(),filter(),如果对象在session缓存中不存在相应的对象,hibernate就会把对象加入到一级缓存,
另外session接口提供两个方法:
evict(Object obj):清除缓存中指定的持久化对象
clear():清除所有缓存中对象
二级缓存:
是一个可插拔式的缓存插件,由SessionFactory管理,但要注意可能出现并发问题
使用场合:
1.很少被修改的数据
2.不是很重要的数据,允许偶尔出现并发的数据
3.不会被并发访问的数据
4.有限实例,被很多地方引用
几个缓存插件:
缓存插件 | hibernate实现类 | 保存类型 | 集群 | 查询 |
EHCach | org.hibernate.cache.EhCachProvider | 内存,硬盘 | N | Y |
OSCach | org.hibernate.cache.OsCachProvider | 内存,硬盘 | N | Y |
SwarmCach | org.hibernate.cache.SwarmCacheProvider | 集群 | Y | N |
JBoss TreeCach | org.hibernate.cache.TreeCacheProvider | 集群 | Y | Y |
缓存插件 | 只读型 | 非严格读写型 | 读写型 | 事务型 |
EHCach | Y | N | Y | N |
OSCach | Y | N | Y | N |
SwarmCach | Y | Y | N | N |
JBoss TreeCach | Y | N | N | Y |
二级缓存的使用:
1.设置缓存粒度,设置并发访问策略
Hibernate允许在类和集合的粒度上设置二级缓存
XXX.hbm.xml文件中
类:
<class name="" table="" catalog="hbql">
<cache usage="read-write">
....
</class>
集合:
<class name="a" table="" catalog="hbql">
<cache usage="read-write"><!--usage设置并发访问策略-->
<set name="b" cascade="save-update" inverse="true">
<cache usage="read-write">加了这部分,a对象关联的b对象不会放入到二级缓存,普通设置反而可以.
....
</set>
....
</class>
2.选择二级缓存插件
hibernate.cfg.xml
<session-factory>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCachProvider |
.....
</session-factory>
缓存属性
属性名称 | 说明 |
hibernate.cache.provider_class | 缓存类名 |
hibernate.cache.use_minimal_puts | 集群有用 |
hibernate.cache.use_query_cache | 查询缓存 |
hibernate.cache.use_second_level_cache | 是否开启二级缓存 |
hibernate.cache.region_prefix | 二级缓存区域名得前缀 |
hibernate.cache.use_structured_entries | 强制hibernate以一定格式存入二级缓存 |
三级缓存:
也称查询缓存
当第一次查询时,会把结果放入二级缓存
使用场合:
1.经常查询的查询语句
2.很少对查询相关的数据作修改
使用:
load()方法:执行时流程:一级缓存->二级缓存->延迟加载->数据库(配置了延迟加载,返回的是一个代理类)
get()不会使用查询缓存
list():第一次查询会填充,三个级别的缓存,返回的是值,如果获得的是ID,那么久根据ID查询值...数据改变缓存自动清空...容易造成N次查询问题
iterator():先获取ID,然后用load()
注意:如果select实体对象的某些列,那么会缓存整个结果集......如果查询结果为某个实体对象集合,只会缓存实体对象的ID值
1.配置二级缓存
2.启动查询缓存
<property name="cache.use_query_cache">true</property>
3.程序中使用
query.setCacheable(true);
query.setCacheRegion("myCacheRegion")//如果不设置,默认使用标准区域