MyBatis 缓存介绍
正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持。
一级缓存
基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session。当 Session 执行 flush 或 close 之后,该 Session 中的所有 Cache 就将清空。
一级缓存是 Session 级的缓存,默认开启。
二级缓存
与一级缓存机制相同,默认也是采用 PerpetualCache 和 HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
缓存数据更新机制
当某一个作用域(一级缓存 Session / 二级缓存 Namespaces)进行了 C(新增)/ U(修改)/ D(删除)操作后,默认该作用域下所有 select 中的缓存将被 clear。
一级缓存试验
我们可以做个试验:先读取一条记录出来,然后去修改数据库的值,再次调用 session 读取出来,看看读取的是修改之前的还是修改后的。
// 第一次查询,从数据库读取
Account account1 = session.selectOne("cn.foxdevelop.mapper.getAccount", 1);
System.out.println(account1.getName());
// 此时手动去数据库修改该记录的 Name 值(比如改为"修改后的名字")
// 第二次查询,同一 session 内,不会再次访问数据库,而是从一级缓存中返回
Account account2 = session.selectOne("cn.foxdevelop.mapper.getAccount", 1);
System.out.println(account2.getName());Code language: JavaScript (javascript)
输出结果两次相同,均为修改前的名字,说明第二次读取命中了一级缓存。
缓存使用注意事项
- 一级缓存要求使用同一个
session。如果session被close()了,缓存就失效了,需要重新创建session。 - 如果想绕过缓存,可以调用
session.clearCache()手动清理缓存:
session.clearCache(); // 清理缓存后,下次查询会重新从数据库读取Code language: JavaScript (javascript)
Previous: MyBatis 调用存储过程