一级缓存(本地缓存)
sqlSession级别的缓存。(相当于一个方法内的缓存)
每一次会话都对应自己的一级缓存,作用范围比较小,一旦会话关闭就查询不到了;
一级缓存默认是一直开启的,是SqlSession级别的一个Map;
与数据库同一次会话期间查询到的数据会放在本地缓存中。
以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;
一级缓存维护在哪里
DefaultSqlSession中只有两个属性可能存放缓存
1)private final Configuration configuration;(全局的,不可能)
2)private final Executor executor;(有可能)
一级缓存什么时候被清空?
从源码可知:在执行update、insert、delete、flushCache="true"、commit、rollback、LocalCacheScope.STATEMENT等情况下,一级缓存就都会被清空。
一级缓存key是什么 ,怎样创建?
Executor接口方法 createCacheKey()
key的生成策略:id + offset + limit + sql + param value + environment id,这些值都相同,生成的key就相同
二级缓存如何开启?
使用:
* 1)、开启全局二级缓存配置:<setting name="cacheEnabled" value="true"/>
* 2)、去mapper.xml中配置使用二级缓存:
* <cache></cache>
* 3)、我们的POJO需要实现序列化接口
二级缓存key是什么 ,怎样创建?
与一级一样
是否应该使用二级缓存?
那么究竟应该不应该使用二级缓存呢?先来看一下二级缓存的注意事项:
1. 缓存是以namespace为单位的,不同namespace下的操作互不影响。
2. insert,update,delete操作会清空所在namespace下的全部缓存。
3. 通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。
4. 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。
如果你遵守二级缓存的注意事项,那么你就可以使用二级缓存。
但是,如果不能使用多表操作,二级缓存不就可以用一级缓存来替换掉吗?而且二级缓存是表级缓存,开销大,没有一级缓存直接使用 HashMap 来存储的效率更高,所以二级缓存并不推荐使用
5. 多表操作对二级缓存的影响 的解决办法,采用 cache-ref 来进行命名空间的依赖能够避免二级缓存,但是总不能每次写一个 XML 配置都会采用这种方式吧,最有效的方式还是避免多表操作使用二级缓存
工作机制:
1、一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中;
* 2、如果会话关闭;一级缓存中的数据会被保存到二级缓存中;新的会话查询信息,就可以参照二级缓存中的内容;
* 3 不同namespace查出的数据会放在自己对应的缓存中(map)
* 效果:数据会从二级缓存中获取
* 查出的数据都会被默认先放在一级缓存中。
* 只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中、
和缓存(一二级)有关的设置/属性
1)、mybatis全局配置文件中配置全局缓存开启和清空
2)mapper.xml中也可以配置一级和二级缓存开启和使用