MyBatis框架-缓存机制

MyBatis是基于JDBC的封装,使数据库操作更加便捷。MyBatis除了对JDBC操作步骤封装之外,也对其性能进行了优化:

  • 在MyBatis中引入缓存机制,用于提升Mybatis检索效率

1. 缓存的工作原理

缓存:用于存储数据的内存

在这里插入图片描述

2. MyBatis缓存

Mybatis缓存分为一级缓存和二级缓存

2.1 一级缓存

一级缓存,也叫做SqlSession级缓存,为每个sqlSession对象单独分配的缓存内存,无需手动开启,可直接使用;多个SqlSession的缓存是不共享的。

特性:

  1. 如果多次查询使用的是同一个SqlSession对象,则第一次查询之后会存放到缓存,后续的查询则直接访问缓存中的存储数据;
  2. 如果第一次查询完成之后,对查询出来的对象进行修改(此修改影响缓存),第二次查询的数据就是缓存中修改后的数据,造成第二次查询的结果与数据库不一致;
  3. 当我们进行查询操作时,需要跳过缓存直接查询数据库时,可以使用sqlSession.clearCache() 来清空当前sqlSession的缓存;
  4. 如果第一次查询之后,第二次查询之前,使用sqlSession执行了修改操作,此操作会使第一次查询的缓存数据失效,因此第二次查询会再次访问数据库进行查询。

2.2 二级缓存

二级缓存:SqlSessionFactory级缓存,通过同一个Factory对象获取的sqlSession可以共享缓存;在应用服务器中SqlSessionFactory是单例的,因此我们二级缓存可以实现全局共享。

一级缓存其共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存,其共享范围为Namespace。开启二级缓存后,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,先在CachingExecutor进行二级缓存的查询。

特性:

  1. 二级缓存默认没有开启,需要在mybatis-config.xml中的settings标签开启
  2. 二级缓存只能缓存实现序列化接口的对象;
    • 序列化:将数据从内存存储到硬盘。(注意:类的属性为实例或者有父类都需要序列化,即为级联序列化,避免数据部分丢失)
    • 反序列化:将数据从硬盘存储到内存。
  3. Mybatis默认关闭二级缓存。
  4. 作用粒度:相同namespace下所有sql语句共享缓存,即:支持不同sqlSession共享缓存。
  5. 数据写入时机:sqlSession.close(),即:sql会话关闭后,统一将当前namespace下的一级缓存写入二级缓存。节约I/O,提高I/O性能。
  6. 二级缓存清理:与清理一级缓存相同,执行commit()方法,但是仅仅针对增删改commit,查询commit无法触发清理。
  7. 关闭单个查询语句二级缓存方式:XXmapper.xml sql语句设置关闭useCache=“false”。

在这里插入图片描述

2.2.1开启二级缓存

  • 配置setting,即:<setting name="cacheEnabled" value="true"/>
  • 指定namespace配置开启,即:<cache/>

2.2.2 二级缓存策略

<!--创建了FIFO策略(first in  first out);30秒刷新一次缓存;最多存储360个对象缓存;缓存对象是只读属性-->
<cache eviction="FIFO" flushInterval="30000" size="360" readOnly="true"/>
  • eviction:缓存的回收策略
  • flushInterval:时间间隔,单位是毫秒
  • size:引用数目,内存大就多配置。默认值是 1024
  • readOnly:true-只读

缓存四大策略:

  • LRU – 最近最少使用的:移除最长时间不被使用的对象,默认
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象

2.4 一二级缓存对比

对比项一级缓存二级缓存
作用范围sqlSessionnameSpace
开启方式默认开启手动开启
存储方式内存硬盘
清理时机增删改查commit()增删改commit()
存储时机执行完sqlsqlSession.close()
关闭方式设置statement模式不启用->全局关闭
设置useCache=“false”->单个sql查询关闭
脏数据场景多线程并发场景,不同线程不同sqlSession更新数据分布式多实例机器部署namespace不规范编写其他表sql
Logo

科技之力与好奇之心,共建有温度的智能世界

更多推荐