关键点:
1.什么时候会把数据放进一级缓存:执行完数据库查询时
2.什么时候会把数据放进二级缓存:关闭sqlSession时(一级缓存无处安放)
3.执行查询时,会优先查找一级缓存。
4.如果二级缓存有数据,就不会执行数据库查询,更不会把数据放入一级缓存。
5.Cache Hit Ratio 缓存命中率专指二级缓存
6.二级缓存的作用域是工厂级别(mapper的同一个namespace中,一般情况下,理解为XXXMapper即可)
有趣的例子:
1.为什么查询完student3后,没关session,直接查询student4,缓存命中率是0.75(说明走了二级缓存)?此时不应该走一级缓存吗?
当session1关闭时,id=1的那条数据,就存入了二级缓存。
接下来的每次查询都会走二级缓存。
没人关心那几个session是否关闭,爱关不关。
只要你查id=1,那么就是走二级缓存,和一级缓存没半毛钱关系。
2.多表联合查询时,清空了session1,第二次查询时走了数据库,为什么查到的还是旧数据,查不到新增的数据?
第二次查询时,session1被清除缓存,所以会去查询二级缓存。
但是!session1从来没有关闭过(清除缓存是用clearCache实现的,session1一直没关),所以不会向二级缓存中存数据,因此二级缓存中没有数据。
最终,只能去数据库查询。
按理说,去数据库查询,查到的应该是最新鲜最热乎的数据。
但是,别忘了一个很重要的东西——事务隔离级别。
我们默认的事务隔离级别是可重复读,会带来幻读问题。
先开启学生事务去执行查询,后开启的班级事务执行新增。
那么,这个班级事务,对于学生事务来说是不可见的。