Ehcache二级缓存,查询缓存,分布式缓存总结

简介:
二级缓存和查询缓存都相当于一个map

二级缓存缓存的keyidvalue为实体对象。一般load(),iterate()使用到二级缓存,list()需要结合查询缓存使用。iterate()和list()区别如下:

iterate()不需要开启查询缓存,它首先发出一个sqlselect s.id from Student s去数据库把id属性列表取出来,然后再根据id列表一个一个load(),如果缓存有从缓存取,如果缓存没有就从数据库取:select s.id,s.name,s.classid from     Student s where s.id=?,取出后再存入二级缓存。Iterate总会发出取id列表的语句。

List()需要开启查询缓存,它首先发出一个sqlselect s.id,s.name,s.classid from Student s…”去数据库取出所有相关实体,并将这些实体存入二级缓存,将此sql语句及一些相关信息作为keyid列表作为值,第二次查询这条语句时就会去根据sql语句及相关信息去key里找,如果有就会把id列表取出一个一个load(),接下来就和iterate一样了。List一般只有第一次发发出取实体列表的语句,以后的id列表就会去查询缓存取id列表,不会再发出sql语句。

 
前提:执行同一hql语句,如:select s from Student s

1.  关闭查询缓存,开启二级缓存时:

第二次查询属性时iterate只会发出获取id列表的sqllist会发出和第一次一样的请求实体的sql

2.  开启查询缓存,开启二级缓存

第二次查询属性时iterate只会发出获取id列表的sqllist不发sql

以上说明iterate只和二级缓存有关,list和二级缓存和查询缓存都有关。

 
查询缓存的key是一个QueryKey(其属性如下),valueid集合。


 
 
  1. public class QueryKey implements Serializable { 
  2.    private final String sqlQueryString;//sql语句 
  3.    private final Type[] types; 
  4.    private final Object[] values; 
  5.    private final Integer firstRow;//要查询的起始数 
  6.    private final Integer maxRows;//要查询的个数 
  7.    private final Map namedParameters; 
  8.    private final EntityMode entityMode; 
  9.    private final Set filters; 
  10.    private final int hashCode; 
  11.    ...... 
果以上属性中有一个不同,查询缓存就不会命中。使用list()时,如果是第一次,查询缓存取出实体列表,然后从实体列表中提取出id列表作为value。如果是查询缓存命中,就会根据QueryKey取出id列表,然后根据id列表去二级缓存中load()对象,如果二级缓存中没有哪个对象,就会根据id去数据库查询,二级缓存中没有n个对象就会去数据库查询n次:select p from pojo p where id=?,因此就会有机会出现传说中n+1问题。

在查询缓存中,查询缓存缓存普通属性,即对于属性的查询,value值为要查询的属性列表,对于实体,value值为实体的id列表,而对于属性的查询由于从value中直接可以查出就不会用到二级缓存,但对于实体的查询,必须结合二级缓存使用。下面对此进行说明:

前提:执行同一hql语句,如:select s from Student sselect s.name from Student s

1.  开启查询缓存,关闭二级缓存时:

第二次查询属性时不会发出sql,第一次查询实体时会发出sql

2.  开启查询缓存,开启二级缓存

第二次查询属性,实体时都不发sql

 
 
对于Ehcache分布式缓存,好像查询缓存不能更新:

在同一系统中,当用Hibernate的方式修改表数据(save,update,delete等等),这时EhCache会自动把缓存中关于此表的所有缓存全部删除掉(这样能达到同步)。但对于两个以上系统部署在不同机子上,并在他们之间配置了ehcache的分布式缓存,当A系统修改表数据(save,update,delete)后,b系统会更新查询缓存吗?

答:好像是不能的,即ehcache的分布式缓存对查询缓存无效。(我在项目中配置了Ehcache的分布式缓存,二级缓存可以生效,但查询缓存不能更新。是不是一个系统中的Hibernate不能够识别其他系统中hibernate是否进行了save,update,delete操作?而Ehcache也没对此进行整合,望知道的大牛给说一下。)










本文转自 yzzh9 51CTO博客,原文链接:http://blog.51cto.com/java999/232572,如需转载请自行联系原作者
目录
相关文章
|
5月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
5月前
|
存储 关系型数据库 分布式数据库
PolarDB 并行查询问题之分布式查询执行过程中的数据分发如何解决
PolarDB 并行查询问题之分布式查询执行过程中的数据分发如何解决
60 1
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
47 5
|
4月前
|
缓存 NoSQL Java
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
缓存与分布式锁、Redisson分布式锁、缓存数据一致性【必须满足最终一致性】
182 14
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
|
3月前
|
存储 缓存 索引
从底层数据结构和CPU缓存两方面剖析LinkedList的查询效率为什么比ArrayList低
本文详细对比了ArrayList和LinkedList的查询效率,从底层数据结构和CPU缓存两个方面进行分析。ArrayList基于动态数组,支持随机访问,查询时间复杂度为O(1),且CPU缓存对其友好;而LinkedList基于双向链表,需要逐个节点遍历,查询时间复杂度为O(n),且CPU缓存对其帮助不大。文章还探讨了CPU缓存对数组增删操作的影响,指出缓存主要作用于读取而非修改。通过这些分析,加深了对这两种数据结构的理解。
59 2
|
3月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
84 4
|
5月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
这篇文章介绍了如何在SpringBoot项目中整合Redis,并探讨了缓存穿透、缓存雪崩和缓存击穿的问题以及解决方法。文章还提供了解决缓存击穿问题的加锁示例代码,包括存在问题和问题解决后的版本,并指出了本地锁在分布式情况下的局限性,引出了分布式锁的概念。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
|
5月前
|
存储 缓存 关系型数据库
查询缓存效果
【8月更文挑战第14天】
40 2
|
5月前
|
存储 SQL 运维
“震撼发布!PolarDB-X:云原生分布式数据库巨擘,超高并发、海量存储、复杂查询,一网打尽!错过等哭!”
【8月更文挑战第7天】PolarDB-X 是面向超高并发、海量存储和复杂查询场景设计的云原生分布式数据库系统
119 1
|
5月前
|
存储 缓存 NoSQL
微服务复杂查询之缓存策略
微服务复杂查询之缓存策略