`

Hibernate中一级缓存、二级缓存及查询缓存的技术性总结

阅读更多

一、 一级缓存

1.         一级缓存只缓存整个对象,不能缓存对象属性;

2.         一级缓存是 Session 级的缓存,不能跨多个 Session 对象来使用;

3.         Session load/get 方法支持一级缓存的读和写;

4.         Query list 接口只支持一级缓存的写入,不能从一级缓存中读出对象。 list 接口加载对象要发出 SQL

5.         Query iterate 接口既支持一级缓存的写入,也能从一级缓存中读取对象(如果有的话)。每次用 iterate 接口查询对象,都要先发 SQL 加载查询对象的 id 列表。如果需要用到某个对象,则根据该对象的 id 从一级缓存中查询,有则直接加载,没有则发出 SQL 从数据库加载(这时会出现 1+N 问题)。

6.         Session save 方法会将 save 的对象放入一级缓存中,因此如果要 save 大批对象,则应该要及时清空一级缓存,可以采用 Session clear() 方法。

7.         一级缓存是 hibernate 默认使用的,无需配置即可使用。

 

二、  二级缓存

1.       二级缓存也是只能缓存整个对象,不能缓存对象属性,而且对 load/get 方法、 list/iterate 方法的在使用上跟一级缓存一样。

2.       与一级缓存不同,二级缓存是 SessionFactory 级的缓存,它允许多个 Session 对象之间共用。

3.       使用二级缓存前必须进行一些准备步骤(以 EhCache 为例 ):

(1)    需要有 EhCache xml 配置文件(设置 EhCache 的“缓存对象最大数目”、“对象是否不失效”、“对象允许的空闲时间”、“对象的生存时间”及“对象数目超额时是否缓存至磁盘”);

(2)    在总配置文件 hibernate.cfg.xml 中启用二级缓存(默认开启,无需显示配置):

< property name = "hibernate.cache.use_second_level_cache" > true </ property >

(3)    指定二级缓存的供应商:

< property name = "hibernate.cache.provider_class" > org.hibernate.cache.EhCacheProvider </ property >

(4)    指定需要缓存的类及缓存方式(可在 hibernate.cfg.xml 或对应的类的 .hbm.xml 中配置):

hibernate.cfg.xml 中配置:

< class-cache usage = "read-only" class = "my.Student" />

Student.hbm.xml 中配置(必须在配置 id 前完成):

< cache usage = "read-only" />

(5)    可以通过 Session 动态设置是否允许对二级缓存进行读和写,方法是: session.setCacheMode(CacheMode.GET) session.setCacheMode(CacheMode.PUT)

(6)    SessionFactory evit() 会将一个对象逐处二级缓存。

 

三、  查询缓存

查询缓存是专为 Query list 方法设计的。对于 iterate() 方法,无论是查询对象属性还是对象本身,查询缓存用与不用都没有区别!

1. 用查询缓存查询属性:

(1)    查询缓存必须要在 hibernate.cfg.xml 中显示启用:

< property name = "hibernate.cache.use_query_cache" > true </ property >

(2)    在代码中如果要用到查询缓存(无论是写还是读缓存),都要进行开启操作,可通过 Query setCacheable( true ) 方法开启;

(3)    查询缓存的生命周期 Session 无关(可以跨 Session 查询 ),当查询关联的表发生改变,那么查询缓存的生命周期结束 ( delete update modify )

(4)    开启查询缓存,并用 Query 查询对象的属性(可以是一个或多个)时,采用 Query list 方法可以把得到的属性集合写入查询缓存中。如果查询缓存已经有了该对象的属性,那么就不会发出 SQL 而直接从查询缓存中取出来;

2. 用查询缓存查询对象:

(5)    如果开启查询缓存并通过 list 接口查询对象,在首次查询时会发出 SQL 从数据库中获取对象,同时将对象的 id 列表放入查询缓存中 ;如果再次用查询缓存查询对象,则会根据该对象的 id 发出 SQL 从数据库中加载对象(这时会发出 N SQL 语句)

(6)    如果同时开启查询和二级缓存,那么(5 )中就不会发出 N SQL 语句了,而是直接从二级缓存中加载。(此时的 list 接口有了读二级缓存的能力了!!!)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics