• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Mybatis一级缓存和二级缓存

武飞扬头像
xinCode79
帮助1

Mybatis一级缓存与二级缓存

缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存可以避免频繁与数据库进行交互,从而提高查询响应速度。
mybaits提供内存支持;
学新通

一级缓存

一级缓存,sqlSession级别的缓存,mybatis级的缓存是默认开启的;

使用场景:

用户发起查询请求,查找某条数据,sqlSession 先去缓存中查找,是否有该数据,如果有,读取;
如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。
但 sqlSession 执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。
如果commit不清空缓存,会有以下场景:
A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。

一级缓存失效场景

不同的SqlSession对应不同的一级缓存
必须使用同一SqlSession,执行同一个查询方法;
如果创建不同的SqlSession,即便执行同一个查询方法,也不会缓存。
同一个SqlSession,但是查询条件不同;
同一个SqlSession两次查询期间执行了任何一次的增删改操作;
同一个SqlSession两次查询期间手动清空了缓存。 sqlSession.clearCache();

有了一级缓存,那么为什么要提供二级缓存呢?

二级缓存是 mapper 级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。

还有一个原因,实际开发中,MyBatis 通常和 Spring 进行整合开发。
Spring 将事务放到 Service 中管理,对于每一个 service 中的 sqlsession 是不同的,
这是通过 mybatis-spring 中的 org.mybatis.spring.mapper.MapperScannerConfigurer 创建 sqlsession 自动注入到 service 中的。
每次查询之后都要进行关闭 sqlSession ,关闭之后数据被清空。
所以 spring 整合之后,如果没有事务,一级缓存 是没有意义的。

二级缓存

二级缓存是 SqlSessionFactory 级别,通过 SqlSessionFactory 创建SqlSession 查询的结果会被缓存。 此后若再次执行相同的查询,结果就会从缓存中获取。mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的;
二级缓存:
开启二级缓存后,用户查询时,会先去二级缓存中找,找不到了再去一级缓存中找;
一级缓存也没有查询到,则查询数据库
二级缓存的流程图
学新通
开启二级缓存:

<settings>  
    <!-- 开启所有Mapper的二级缓存  -->  
    <setting name="cacheEnabled" value="true"/>  
</settings>

简化配置:

<cache/>

POJO 类实现 Serializable 接口
public class User implements Serializable {

}
二级缓存必须在SqlSession关闭或提交之后有效

sqlSession1.close(); // 或者 sqlSession1.commit();

sqlSession2.close(); // 或者 sqlSession2.commit();

一二级缓存的弊端

  • 没有缓存命中率
    • MyBatis的一级缓存只适用于同一个SqlSession,因此它在多个SqlSession之间是无效的。这意味着如果您需要执行多个查询,并且这些查询需要在不同的SqlSession中执行,那么一级缓存就无法提供任何帮助。这种情况下,每次查询都需要从数据库中获取数据,因此缓存命中率为0。
  • 线程安全问题
    • MyBatis的SqlSession并不是线程安全的,因此在多线程环境下使用一级缓存可能会导致问题。如果两个线程共享同一个SqlSession,并且其中一个线程执行了一个查询,那么另一个线程可能会从缓存中获取到不正确的结果。因此,如果您在多线程环境中使用MyBatis,请确保每个线程都有自己的SqlSession。
  • 没有清除机制
    • MyBatis的一级缓存没有自动清除机制。这意味着如果您在SqlSession中执行了更新、插入或删除操作,那么这些操作将会使缓存失效。但是,如果您在执行这些操作之前没有清除缓存,那么缓存中的数据将会是旧的,这可能会导致应用程序中的错误。
  • 内存泄漏问题
    • MyBatis的一级缓存存储在内存中,因此如果您在应用程序中长时间使用同一个SqlSession,那么缓存中的数据可能会占用大量内存。这可能会导致内存泄漏问题,尤其是在长时间运行的应用程序中。
      基于这些问题,我们可以看出MyBatis的一级缓存并不是最好的选择。因此,如果您需要缓存查询结果以提高性能,可以考虑使用二级缓存。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggijgb
系列文章
更多 icon
同类精品
更多 icon
继续加载