首页 > 其他分享 >Mybatis 一级缓存与二级缓存

Mybatis 一级缓存与二级缓存

时间:2023-06-06 16:23:43浏览次数:42  
标签:缓存 一级 SqlSession 查询 二级缓存 Mybatis

本文转载于:Mybatis一级缓存与二级缓存的区别你知道吗

Mybatis 缓存

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

MyBatis 提供了对缓存的支持,分为一级缓存和二级缓存,如下图所示:
image

我们先大致了解下 MyBatis 一级缓存与 MyBatis 二级缓存:

  • 一级缓存:SqlSession级别的缓存,缓存的数据只在SqlSession内有效。

  • 二级缓存:mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的,二级缓存需要我们手动开启。

下面我们再分别详解两者的原理与区别。

Mybatis 一级缓存

1.为什么需要 Mybatis 一级缓存
当我们使用 Mybatis 进行数据库的操作时候,会创建一个 SqlSession 来进行一次数据库的会话,会话结束则关闭 SqlSession 对象。

如果我们很有可能多次查询完全相同的 sql 语句,每一次查询都查询一次数据库,那查询数据库代价是比较大的,这会导致系统的资源浪费。

为了解决这个问题,Mybatis 对每一次会话都添加了缓存操作,不用相同的 SQL 每次都需要查询数据库,这就是 Mybatis 一级缓存的作用。

2.Mybatis 一级缓存的实现
我们知道对 SqlSession 的操作,Mybatis 内部都是通过 Executor 来执行的,Executor 的生命周期和 SqlSession 是一致的。

Mybatis 在 Executor 中创建了本地缓存(一级缓存),如下图所示:
image

大致的流程如下:

第一次查询用户 id 信息,先去缓存中查询是否有,如果没有,从数据库中查询用户信息,得到用户信息后在将用户信息储存到一级缓存中。

如果 SqlSession 去执行 commit 操作(插入、更新、删除),清空 SqlSession 中的一级缓存,保证缓存中始终保存的是最新的信息,避免脏读。

第二次查询用户 id 信息,先去缓存中查询,如缓存中有,直接从缓存中获取。

注意:两次查询须在同一个 Sqlsession 中完成,否则将不会走 Mybatis 的一级缓存。

在 Mybatis 与 Spring 进行整合开发时,事务控制在 service 中进行,重复调用两次 servcie 将不会走一级缓存,因为在第二次调用时 session 方法结束,SqlSession 就关闭了。

3.Mybatis一级缓存配置
Mybatis 一级缓存的范围有 SESSION 和 STATEMENT 两种,默认是 SESSION。

如果不想使用一级缓存,可以把一级缓存的范围指定为 STATEMENT,这样每次执行完一个 Mapper 中的语句后都会将一级缓存清除。

如果需要更改一级缓存的范围,可以在 Mybatis 的配置文件中,在下通过 localCacheScope 指定。

<setting name="localCacheScope" value="STATEMENT"/>

Mybatis 二级缓存

1.为什么需要 Mybatis 二级缓存?
MyBatis 一级缓存最大的共享范围就是一个 SqlSession 内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存。

2.Mybatis 二级缓存的实现
开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示。
image

二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

MyBatis 是默认关闭二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。

Mybatis 一级缓存与二级缓存的区别
1)一级缓存 Mybatis 的一级缓存是指 SqlSession,一级缓存的作用域是 SqlSession, Myabits 默认开启一级缓存

在同一个 SqlSession 中,执行相同的 SQL 查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。当执行两次查询的中间发生了增、删、改的操作 commit 后,则 SqlSession 的缓存会被清空

Mybatis 的内部缓存使用一个HashMap,key 为hashcode+statementId+sql语句。value 为查询出来的结果集映射成的 Java 对象。

2) Mybatis二级缓存是默认不开启的,作用于一个 Application,是 Mapper 级别的,多个 SqlSession 使用同一个 Mapper 的 sql 就能够使用二级缓存。

标签:缓存,一级,SqlSession,查询,二级缓存,Mybatis
From: https://www.cnblogs.com/cloudrich/p/17460863.html

相关文章

  • MyBatis-plus学习笔记
    1、MyBatis-Plus(简称MP)是一个 MyBatis 的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。2、特性:无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作强大的CRUD操作......
  • MybatisPlus代码生成器
    MybatisPlus代码生成器这里讲解的是新版(mybatis-plus3.5.1+版本),旧版不兼容官方文档:https://baomidou.com/(建议多看看官方文档,每种功能里面都有讲解)https://cloud.tencent.com/developer/article/2119707配置这里的配置表格和官方文档一致手动配置代码生成器建表,插入数......
  • 字符集问题(mybatis 插入mysql中文乱码,入参是中文)
    1.启动/停止/重启/状态servicemysqldstartservicemysqldstopservicemysqldrestartservicemysqldstatus  mysqld是守护进程脚本,init.d不是mysql的home2.home/进入控制台/usr/lib64/mysqlmysql-uroot-p切换数据库usesomedb查看该数据库字符集......
  • mybatis参数处理2
    1. 多个参数  811.1  需求:通过name和sex查询  81test中的com.powernode.mybatis.testStudentMapperTest类中的testSelectByNameAndSex//多个参数81@TestpublicvoidtestSelectByNameAndSex(){SqlSessionsqlSession=SqlSessionUtil.openSession();......
  • mybatis查询语句专题
    前言:打包⽅式:jar 引⼊依赖:mysql驱动依赖、mybatis依赖、logback依赖、junit依赖。 引⼊配置⽂件:jdbc.properties、mybatis-config.xml、logback.xml 创建pojo类:Car 创建Mapper接⼝:CarMapper 创建Mapper接⼝对应的映射⽂件:com/powernode/mybatis/mapper/CarMapper.xml 创建单......
  • mybatis中使用where in
    MyBatis支持使用标签来实现wherein语句的写法。下面是一个示例,假设我们有一个User实体类,其中包含一个List类型的属性roles``,表示用户拥有的角色列表。我们想要查询所有拥有admin或user`角色的用户:<selectid="findUsersByRole"resultType="User">SELECT*FROMuserWHER......
  • 手把手教你AspNetCore WebApi:缓存(MemoryCache和Redis)
    前言这几天小明又有烦恼了,系统上线一段时间后,系统性能出现了问题,马老板很生气,叫小明一定要解决这个问题。性能问题一般用什么来解决呢?小明第一时间想到了缓存。什么是缓存缓存是实际工作中非常常用的一种提高性能的方法。缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能......
  • Hash 缓存
    原文点此跳转输出文件名(Hash)静态资源缓存是前端性能优化的一个点,所以在前端开发过程中,一般会最大限度的利用缓存(这里主要是强缓存)。如果设置了强缓存后,每次当我们部署了新的项目文件到线上的时候,因为文件名称没有变化,浏览器就会读取本地缓存中的bundle.js文件,导致了我们新的bund......
  • 应用问题解决——缓存穿透、缓存击穿、缓存雪崩
    一、缓存穿透缓存穿透:key对应的数据在数据源并不存在,每次针对key的请求从缓存中获取不到,请求都会压到数据源,从而可能压垮数据源,比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库现象:1、应用服务器压力变大2、redis命中率......
  • Redis(四) -- 缓存
    缓存缓存更新方式这是决定在使用缓存时就该考虑的问题。设置缓存数据的TTL,当缓存数据失效后,如果有系统要请求,则会查询数据库并插入缓存(被动更新)不友好在各类会往mysql写入数据的系统中,植入更新缓存的逻辑(判断哪些表的数据是热点数据,那么就可以在这些表数据的更新操作逻辑中......