Mybatis 一级缓存和二级缓存原理区别 (图文详解)

Mybatis 一级缓存和二级缓存原理区别 (图文详解)

Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别@mikechen

Mybatis缓存

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

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

Mybatis 一级缓存和二级缓存原理区别 (图文详解)

我们先大致了解下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中创建了本地缓存(一级缓存),如下图所示:

Mybatis 一级缓存和二级缓存原理区别 (图文详解)

大致的流程如下:

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

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

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

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

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

3.Mybatis一级缓存配置

mybatis一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION。

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

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


Mybatis二级缓存

1.为什么需要Mybatis二级缓存?

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

2.Mybatis二级缓存的实现

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

Mybatis 一级缓存和二级缓存原理区别 (图文详解)

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

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

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

Mybatis一级缓存与二级缓存的区别

1)一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Myabits默认开启一级缓存。

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

每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。

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

以上

作者简介

陈睿|mikechen,10年+大厂架构经验,《BAT架构技术500期》系列文章作者,分享十余年架构经验以及面试心得!

阅读mikechen的互联网架构更多技术文章合集

Java并发|JVM|MySQL|Spring|Redis|分布式|高并发|架构师

Original: https://www.cnblogs.com/mikechenshare/p/16714646.html
Author: mikechen的互联网架构
Title: Mybatis 一级缓存和二级缓存原理区别 (图文详解)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/616144/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring系列2:Spring容器基本概念和使用

    本文内容 简单回顾IoC和DI概念 Spring容器的概念 的xml配置和初始化 容器的基本使用 bean的定义和初始化配置 简单理解IoC和DI概念 什么是IoC控制反转? 通俗…

    Java 2023年6月5日
    0124
  • Spring Boot 入门(二)单元测试

    *创建测试 选中类名,使用快捷键”Alt+Enter”,选择”Create Test” 勾选被测试的成员 编写单元测试 packag…

    Java 2023年6月5日
    076
  • 类加载

    加载—–连接(验证—准备—解析)——初始化: 加载就是 将类的二进制字节码载入JVM中、将这个字节流代表的存…

    Java 2023年6月9日
    097
  • 数字化来势汹汹,低代码起势,JNPF助力企业定制专属BIM

    引言 当前的中国建筑市场极大,而建筑行业在迅速发展的同时也需要科学的可持续发展,所以施工企业面临着极其严峻的竞争挑战。在此背景下,国内企业运用BIM的比例持续升高是发展的必然。BI…

    Java 2023年6月5日
    0103
  • 周年庆活动火热进行中!你想了解的都在这,点击即可查看更多活动详情!

    好消息! 好消息! 好消息! 为迎接引迈信息三周年来临之际,我司特推出此次周年庆典活动,以此回馈这些年来一直支持着我们的客户与合作商们。 这三年走来,引迈不断创新,不断突破,致力于…

    Java 2023年6月5日
    0133
  • 附002.Nginx代理相关模块解析

    一 ngx_http_proxy_module模块 proxy_pass URL; Context: location, if in location, limit_except …

    Java 2023年5月30日
    085
  • springboot中bean注入失败的四种原因

    1、被注入的对象没有被spring扫描到,此时需要添加对应的包扫描路径。 @ComponentScan 2、需要自动注入的对象不是spring加载,而是new的方式创建 需要自动注…

    Java 2023年6月7日
    074
  • 几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比

    AJAX是 web2.0的基石,现在网上流行几种开源的AJAX框架,比如:jQuery,Mootools,Dojo,Ext JS等等,那么我们到底在什么情况下该使用那个框架? 让我…

    Java 2023年6月9日
    090
  • websocket2.0 适用于发送的数据体很大

    当websocket发送的数据体积很大,需要的传输时间很长,并且传输频率较高的情况下使用 pom配置 一、创建内部的缓存对象 二、创建websocket对象 三、创建定时任务进行状…

    Java 2023年6月16日
    074
  • RocketMQ基本API使用

    RocketMQ基本API使用 基于原生客户端 <dependency> <groupid>org.apache.rocketmq</groupid&…

    Java 2023年6月6日
    0101
  • Java 字符串格式化和工具类使用

    前言 我们在做项目时候经常需要对字符串进行处理,判断,操作,所以我就总结了一下 java字符串一些常用操作,和推荐比较好用我在自用的工具类,毕竟有轮子我们自己就不用重复去写了,提供…

    Java 2023年6月13日
    090
  • docker 安装mysql5.7

    拉取镜像 docker pull mysql:5.7 准备数据目录 mkdir -p /mall/docker/mysql/conf mkdir -p /mall/docker/m…

    Java 2023年6月9日
    052
  • Spring事务处理

    Spring的事务处理 Spring提供一种处理事务的统一模型 1、 事务 (1)事务是指一组sql语句的集合 (2)事务ACID原则:原子性、一致性、隔离性、持久性 2、 Spr…

    Java 2023年6月5日
    0102
  • Mysql进击篇-存储引擎、索引、sql优化、视图、锁、innoDb、管理

    1.存储引擎 (1)连接层最上层是一些客户端和连接服务,主要完成一些类似于连接处理,授权认证、以及相关的安全方案,服务器也会为安全接入的每个客户端验证它所具有的操作权限(2)服务层…

    Java 2023年6月8日
    086
  • 商城秒杀系统总结(Java)

    本文写的较为零散,对没有基础的同学不太友好。 一、秒杀系统项目总结(基础版) classpath 在.properties中时常需要读取资源,定位文件地址时经常用到 classpa…

    Java 2023年6月7日
    0115
  • 从边际成本角度思考程序员职业

    程序员职业提供的是软件知识服务。 程序员真的是以写代码为生?yes and no. 既是,也不全是。 从表面来看,程序员产出代码和软件,领工资过日子。再往里一层看,程序员职业提供的…

    Java 2023年6月9日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球