MyBatis 中的本地缓存和二级缓存的作用是什么?怎么实现的?

本地缓存

作用:

SqlSession 级别的缓存,默认开启,在 MyBatis 配置文件中可以修改 MyBatis 文件中 < setting> 标签 localCacheScope 参数值改变缓存的作用域。statementId、boundSql.getSql() 执行 sql、查询参数、RowBounds 都相同,即认为是同一次查询,返回缓存值。


实现原理:

每个 SqlSession 对象包含一个 Executor 对象,Executor 对象中 localCache 属性使用 PerpetualCache 对象缓存查询数据;从源码中看 DefaultSqlSession 的 close、commit、rollback、insert、delete、update 相关的方法都会触发 BaseExecutor 对象清掉缓存。

 

二级缓存

作用:
MappedStatement 级别的缓存,默认不开启,可以在 Mapper xml 中通过 < cache> 标签开启 或者 MyBatis 文件中 < setting> 标签设置 cacheEnabled 参数为 true 全局开启 或者 mapper xml 配置文件中的 select 节点需要加上属性 useCache,在 SqlSession 关闭或提交之后才会生效。


开启二级缓存的默认作用摘自官网

  • 映射语句文件中的所有 select 语句的结果将会被缓存。

  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。

  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。

  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。

  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。

  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

实现原理:

  • XMLMappedBuilder 解析 Mapper xml 中的 < cache>、< cache-ref> 标签

  • 通过 builderAssistant 对象 addMappedStatement 方法,设置 cache 信息到 MappedStatement 对象内

  • CachingExecutor 对象的 query 方法先 MappedStatement 对象中 getCache() 获取缓存 Cache 对象,如果没有查到则到 BaseExecutor 中查询,走本地缓存逻辑

 

 


【Java面试题与答案】整理推荐

  • 基础与语法
  • 集合
  • 网络编程
  • 并发编程
  • Web
  • 安全
  • 设计模式
  • 框架
  • 算法与数据结构
  • 异常
  • 文件解析与生成
  • Linux
  • MySQL
  • Oracle
  • Redis
  • Dubbo

 

你可能感兴趣的:(java)