Hibernate缓存学习笔记

一级缓存(在同一个Session中,缓存实体对象,生命周期与Session一致)
查询实体
1.执行两次load,get,第二次会从缓存里取
2.执行两次iterate
HQL:from Student s where s.id=1
第一次:
首先:select student_id from t_student where student_id=1;查询出ID列表
然后:select * from t_student where student_id=1;根据ID查询实体
第二次:
select student_id from t_student where student_id=1;查询出ID列表
不会发出SQL,因为缓存里有。
3.先save,后load或get,不会发SQL,因为save后,它会往缓存里放一份

查询普通属性
1.执行两次iterate
HQL:select s.name from Student s where s.id=1;
第一次:select name from t_student where id=1;没有放入缓存
第二次:select name from t_student where id=1;
缓存管理
一级缓存是无法取消,但可以管理(session.evict(object),session.clear())
Hibernate导入数据:因为save方法,每执行一次就会往缓存里让一份,所以可以每隔小量数据,
先session.flush(),然后session.clear(),避免内存溢出。
如果数据量特别大,可以采用jdbc,如果jdbc也不能满足要求,可采用数据库的专门导入工具

二级缓存(进程级缓存,缓存实体对象,生命周期与SessionFactory一致)
配置:1.首先到Hibernate根目录下的etc下的ehcache.xml拷贝到classpath可以搜索到的地方
它有个默认配置选项
<defaultCache
maxElementsInMemory="10000" //内存中可以存一万个对象
eternal="false" //这些对象在内存中不是永久有效的,与下面两个属性是互斥的
timeToIdleSeconds="120" //空闲的时间
timeToLiveSeconds="120" //缓存对象生命是多长(120秒)
overflowToDisk="true" //超过10000个对象时,是否要保存到磁盘上.保存路径为如下
/>
<diskStore path="java.io.tmpdir"/> 这表示操作系统的临时路径,
在WINDOWS上为C:\WINDOWS\temp\
2.在Hibernate.cfg.xml中开启二级缓存将hibernate.cache.use_second_level_cache设置为true
3.指定缓存产品提供商
将hibernate.cache.provider_class设置为 org.hibernate.cache.OSCacheProvider
4.在映射文件中指定缓存策略
<cache usage="read-only"/>
也可以在配置文件中指定<class-cache class="com.shadow.Student" usage="read-only"/>
我个喜欢配置在配置文件中,这样查看比较方便(read-only效率最高,read-write也可以)
查询实体
1.在两个不同的Session中,get,load,都会使用二级缓存
一级缓存与二级缓存的交互
session.setCacheMode(CacheMode.GET | CacheMode.PUT | Cache.NORMAL)

查询缓存(只有query.list()使用查询缓存,query.list()也只使用查询缓存)
缓存普通属性结果集,对实体对象的结果集只缓存ID,如果当前关联的表发生的修改,那么查询缓存生命周期结束
配置:启用查询缓存 将hibernate.cache.use_query_cache设置为true
在程序中显式的查询缓存query.setCacheable(true)
HQL:select s.name from Student s
一.查询普通属性
1.在同一个Session中,执行两次query.list();
1>关闭二级缓存,关闭查询缓存,会发两次SQL
2>关闭二级缓存,打开查询缓存,第一次会发,第二次不会发
2.开启两个Session,分别调用query.list();
关闭二级缓存,打开查询缓存,第一次会发,第二次不会发,查询缓存的生命周期与Session无关
3.开启两个Session,分别调用query.iterate();
关闭二级缓存,打开查询缓存,两次都会发,查询缓存对query.iterate()方法无效,即query.iterate()
不使用查询缓存
二.查询实体对象
1.开启两个Session,分别调用query.list();
HQL:select s from Student s
1>关闭二级缓存,关闭查询缓存,会发两次SQL
2>关闭二级缓存,开启查询缓存,第一次会发一条SQL:select * from t_student
第二次会发n条SQL,都是根据Id来查询,SQL:select * from t_student where id=?
因为开启了查询缓存,对于实体对象只会缓存实体Id
3>开启二级缓存,开启查询缓存,第一次会发,第二次不会发
2.在同一个Session中,执行两次query.list();
1>关闭二级缓存,关闭查询缓存,会发两次SQL,因为query.list()只存不取
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值