1. Hibernate的缓存类型:一级缓存、二级缓存和查询缓存
一级缓存:又叫事务级缓存,其生命周期和session的一致。
二级缓存:又叫进程级缓存,其生命周期和sessionFactory的一致。Hibernate默认开启该缓存
查询缓存:生命周期不确定,当缓存的数据对应的表发送变化时,查询缓存中数据失效。
2. Hibernate各级缓存的对象
一级和二级缓存只缓存实体对象。查询缓存只缓存不同属性和实体对象的ID。
3. 一级缓存和二级缓存的管理
一级缓存主要是通过session中的evict()和clear()方法来清除缓存中的数据
二级缓存通过sessionFactory中的evict()和clear()方法来清除缓存中的数据
4. 一级缓存和二级缓存的交互
主要是通过设置session的缓存模式来和二级缓存进行交互。
设置session.setCacheMode(CacheMode.PUT),session只会向二级缓存中插入数据而不会获取二级缓存中的数据(即使存在,也不会获取数据)。
设置session.SetCacheMode(CacheMode.GET),session只会从二级缓存中获取数据而不会放入数据到二级缓存。
5. 查询缓存
缓存不受session的影响,能实现sesion之间的共享。
缓存只对query.list()起作用,对iterate()不起作用。设置查询缓存后,当查询实体对象时会缓存实体对象的ID。
查询缓存后,list()先到查询缓存中查找对应的实体ID,然后根据ID到缓存中找对应的实体对象,若缓存中不存在对应数据(将会根据ID连续发出查询实体的SQL)则会发出SQL来查询该ID对应的单个实体对象。(缓存的ID必须和list()中要查询的ID完全相同,否则将直接发SQL,而不会使用缓存)。也就是说要让list()使用二级缓存中的数据,就必须开启查询缓存,并保证list()查询到的实体的所有ID在查询缓存中全部存在。
只要没有开启查询缓存list()都会发出SQL,即便是缓存中有数据。
6.加载方法介绍
get和load都支持缓存。默认会将数据插入缓存,同时,也从缓存中获取数据。
- <property name="hibernate.cache.use_second_level_cache">true</property>
- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
同时,必须加入相应的缓存产品配置文件。如ehcache.xml
查询缓存:
- <property name="hibernate.cache.use_query_cache">true</property>
在代码中必须开启查询缓存:query.setCacheable(true)
list()只会插入数据到缓存,而不会从缓存取数据(除非设置查询缓存)。
iterate()会先发出查询ID列表的SQL语句,然后根据ID先到缓存中查询数据,若没有数据才会根据ID发出SQL。(若缓存中没有对应实体数据,易产生N+1问题)
7.各级缓存的基本配置
一级缓存:默认已配置。
二级缓存:
配置文件: