mybatis 一级缓存 二级缓存的理解
一级缓存
- 默认开启.是基于sqlsesion层面的 在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。 一级缓存的作用域是同一个SqlSession,在第一个sqlSession执行相同的sql语句后结果放在内存中,第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了
(什么是sqlsesion层面? 个人理解就是同一事务下对数据库的一次链接,所谓sqlsesion层面的,也就是在一个事务(会话)内的所有数据库请求)
例:
在同一个事务(会话)内 多次请求数据库,并且查询sql条件完全一致,中间没有对该sqlsesion的增删改操作,则第二次不会去请求数据库,直接从一级缓存中取出查询数据。
在使用中我们可以打开mybits的sql日志,会发现二次请求,并不会打印sql执行日志,则说明一级缓存生效。
从业务代码层面分析,一般也不会出现这种场景,直接拿第一次的查询结果去使用即可。
二级缓存
默认开启, 基于nameSpace层面
在mybits的使用中 会配置对应的XXXMapper.xml文件 并且在文件中配置相应的NameSpace 在同一个NameSpace下的缓存共享
多个会话请求 请求数据库 并且查询sql条件完全一致,中间没有对该NameSpace的增删改操作。
在使用中多次会话请求中,打开sql日志,出现hit cache ….表示命中二级缓存
开启二级缓存条件 设置全局
需要开启二级缓存的mapper下增加 开启二级缓存
注意点:1.使用二级缓存的实体类对象必须实现序列化接口
2.二级缓存对直接修改数据库的情况无法检测,会产生脏读情况。
重点:不论是一级缓存还是二级缓存 粒度不是基于表 而是sqlsesion 和 nameSpace下 只要该sqlsesion 或namespace下发生更新 删除 新增 操作 都会删除原有缓存,跟表没关系,所以在应用过程中要保证 同一个namespace下 只对一个表操作,杜绝使用连表操作的缓存。
缓存顺序
- 先看二级缓存中有没有, 有就直接返回, 没有就往下走
- 再看一级缓存中有没有, 有就直接返回, 没有就往下走
- 再去查询数据库, 将查询结果放到一级缓存中
- 如果一级缓存的 SqlSession 提交或者关闭, 会将一级缓存中数据提交到二级缓存
在以下场景中,推荐使用二级缓存。
- 以查询为主的应用中,只有尽可能少的增、删、改操作;
- 绝大多数以单表操作存在时,由于很少存在互相关联的情况,因此不会出现脏数据。