mybatis一级缓存和二级缓存的区别及说明

目录
  • 结论
  • 源码
  • 一级缓存
  • 二级缓存

我们通常说mybatis中一级缓存是sqlSession级别的,二级缓存是namespace级别的,这篇笔记主要来记录下这么说的原理

结论

先说结论吧,一级缓存之所以说是sqlSession级别的,是因为一级缓存的数据是存放在了sqlSession的一个内部属性中,所以,每次openSession()开启一个sqlSession之后,一级缓存就会失效

二级缓存之所以可以跨sqlSession,是因为二级缓存的数据,是存放在mappedStatement对象中的一个内部属性中,这里说的内部属性其实不太准确,但是先忽略,后面会详细解释

我们知道,mybatis在启动的时候,会解析全局配置文件,会把mapper.xml文件中的一个个sql片段,解析成一个个mappedStatement对象,所以,这里二级缓存自然也就是namespace级别的

源码

在mybatis源码中,CachingExecutor是二级缓存的处理类,BaseExecutor是一级缓存的处理类

我们先来看一级缓存的处理

一级缓存

这里是一级缓存的处理,会发现,这里是从localCache中根据key获取value的,换而言之,这里的localCache大概率就是我们所谓的一级缓存了,我们看下localCache是在哪里赋值的

可以看到,localCache是在BaseExecutor的构造函数中,每次new 出来的,所以,这里我们可以知道,只要new 一个BaseExecutor对象,就会有一个localCache,那对应的一级缓存就不一样,我们再看下,在正常的sql执行过程中,BaseExecutor是在什么时候初始化的

org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
    org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
        org.apache.ibatis.session.Configuration#newExecutor()

这里可以看到,在通过openSession()初始化sqlSession对象的时候,就会初始化一个executor对象

所以,我们说一级缓存是executor级别的

二级缓存

我们接着来看二级缓存的逻辑

二级缓存是从这里的tcm这个对象中来获取的,但是实际上,我们调到tcm.getObject()方法中,会发现实际上是从入参的cache来获取的,所以我们需要看下这里入参的cache是从哪里获取到的

可以看到这个方法的第一行,是从MappedStatement对象中获取到的

可以看到,mappedStatement对象是从configuration对象中获取到,所以我们要看下configuration的mappedStatement对象是什么时候赋值的

org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement()

在这个方法中,可以看到,最终会把statement对象设置的configuration中,同时需要注意的是,我们用到的cache对象是从currentCache来的,所以我们需要关注,currentCache是从哪里来的?

在同类中,org.apache.ibatis.builder.MapperBuilderAssistant#useNewCache

这个方法中,会给currentCache赋值

如果看过前面两篇关于mybatis源码解析博客的,应该会比较清楚,这里的useNewCache()方法,就是在解析mapper.xml文件中的节点时,调用的

org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement
    org.apache.ibatis.builder.xml.XMLMapperBuilder#cacheElement
        org.apache.ibatis.builder.MapperBuilderAssistant#useNewCache

截图中的这个方法是解析一个mapper.xml的逻辑

所以,我们发现

在解析mapper.xml文件的时候,会解析配置的节点,在解析这个节点的时候,会初始化一个cache对象,这个cache对象,会赋值给currentCache然后继续解析一个个sql片段,这一个mapper.xml文件中,无论有多少个sql,这里的currentCache都是一样的二级缓存在使用的时候,会从mappedStatement对象中获取currentCache,如果currentCache不为null,就表示需要使用二级缓存然后从currentCache,根据key获取value这里需要知道的是:这里的currentCache,也是对PerpetualCache的包装,以前文章有介绍过,这次不做过多的解读

所以,我们说二级缓存是namespace级别的

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 关于mybatis的一级缓存和二级缓存的那些事儿

    一.缓存是什么 缓存其实就是存储在内存中的临时数据,这里的数据量会比较小,一般来说,服务器的内存也是有限的,不可能将所有的数据都放到服务器的内存里面,所以, 只会把关键数据放到缓存中,缓存因为速度快,使用方便而出名! 二.为什么需要缓存 BS架构里面,用户的所有操作都是对数据库的增删改查,其中查询的操作是最多的,但如果用户想要某个数据时每次都去数据库查询,这无疑会增加数据库的压力,而且获取时间效率也会降低,所以为了解决这些问题,缓存应用而生,使用了缓存之后,服务器只需要查询一次数据库,然后将数据

  • 一文搞懂MyBatis一级缓存和二级缓存

    目录 前言 一. 一级缓存机制展示 二. 一级缓存源码分析 三. 二级缓存机制展示 1. 场景一 2. 场景二 3. 场景三 4. 场景四 5. 场景五 四. 二级缓存的创建 五. 二级缓存的源码分析 总结 前言 在本篇文章中,将结合示例与源码,对MyBatis中的一级缓存和二级缓存进行说明. MyBatis版本:3.5.6 正文 一. 一级缓存机制展示 在MyBatis中如果多次执行完全相同的SQL语句时,MyBatis提供了一级缓存机制用于提高查询效率.一级缓存是默认开启的,如果想要手动配置

  • SpringBoot + Mybatis-plus实战之Mybatis-plus的一级缓存、二级缓存

    前言 现在的JAVA行业,貌似已经是SpringBoot + SpringCloud 的天下了,早期的SSH,SSM框架已经老去,与SpringBoot相结合的JPA框架虽然省去了很多的增删改查sql,但是比较笨拙,在面对一些复杂多变的逻辑时常常力不从心,而相对应的Mybatis由于其高度的灵活性受到广大JAVA攻城狮的欢迎.之前整合过了springboot+mybatis,前几天看到一个面试的问一个问题,Mybatis的一级缓存,二级缓存.我想这个应该也是一个重点吧,所以今天决定来详细解读一下

  • Mybatis详细对比一级缓存与二级缓存

    目录 基本要点 1.缓存 2.一级缓存(默认开启,无法关闭) 3.二级缓存 4.缓存查询原理 基本要点 1.缓存 什么是缓存? 存在内存中的临时数据,我们可以把用户经常查询的数据存放到缓存中,当用户重复查询时,我们可以直接从缓存中查询,提高查询效率,可以解决高并发系统的性能问题 为什么使用缓存? 减少和数据库交互次数,减轻数据库的压力,提高系统效率 什么样的数据能使用缓存? 经常查询且不经常改变的数据 2.一级缓存(默认开启,无法关闭) 1)一级缓存的有效区间是sqlSession从创建到关闭的

  • MyBatis一级缓存与二级缓存原理与作用分析

    目录 缓存的作用 MyBatis 的缓存结构 一级缓存 二级缓存 缓存的作用 在 Web 系统中,最重要的操作就是查询数据库中的数据.但是有些时候查询数据的频率非常高,这是很耗费数据库资源的,往往会导致数据库查询效率极低,影响客户的操作体验.于是可以将一些变动不大且访问频率高的数据,放置在一个缓存容器中,用户下一次查询时就从缓存容器中获取结果. MyBatis 的缓存结构 MyBatis 系统中默认定义了两级缓存:一级缓存和二级缓存: MyBatis 一级缓存是一个 SqlSession 级别,

  • Mybatis 一级缓存与二级缓存的实现

    mybatis缓存 mybatis作为一个流行的持久化工具,缓存必然是缺少不了的组件.通过这篇文章,就让我们来了解一下mybatis的缓存. mybatis缓存类型 说起mybatis的缓存,了解过的同学都知道,mybatis中可以有两种缓存类型: 第一种,我们通常称为以及缓存,或者sqlSession级别的缓存,这种缓存是mybatis自带的,如果mapper中的配置都是默认的话,那么一级缓存也是默认开启的. 第二种,就是非sqlSession级别的缓存了,我们通常称为二级缓存,mybatis

  • mybatis教程之查询缓存(一级缓存二级缓存和整合ehcache)

    1 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. 2 mybatis持久层缓存 mybatis提供一级缓存和二级缓存 mybatis一级缓存是一个SqlSession级别,sqlsession只能访问自己的一级缓存的数据,二级缓存是跨sqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的. 3 一级缓存 3.1 原

  • Mybatis 一级缓存和二级缓存原理区别

    目录 Mybatis缓存 Mybatis一级缓存 1.为什么需要Mybatis一级缓存 2.Mybatis一级缓存的实现 3.Mybatis一级缓存配置 Mybatis二级缓存 1.为什么需要Mybatis二级缓存? 2.Mybatis二级缓存的实现 Mybatis一级缓存与二级缓存的区别 Java面试经常问到Mybatis一级缓存和二级缓存,今天就给大家重点详解Mybatis一级缓存和二级缓存原理与区别 Mybatis缓存 缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存可以避免

  • 深入理解MyBatis中的一级缓存与二级缓存

    前言 先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能. 一级缓存 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据.不同的sqlSession之间的缓存数据区域是互相不影响的.也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的. 一级缓

  • Mybatis的一级缓存和二级缓存原理分析与使用

    目录 Mybatis的一级缓存和二级缓存 1 Mybatis如何判断两次查询是完全相同的查询 2 二级缓存 2.1 二级缓存配置 2.2 二级缓存特点 2.3 配置二级缓存 2.4 测试 Mybatis的一级缓存和二级缓存 Mybatis会将相同查询条件的SQL语句的查询结果存储在内存或者某种缓存介质中,当下次遇到相同的SQL时不执行该SQL,而是直接从缓存中获取结果,减少服务器的压力,尤其是在查询越多.缓存命中率越高的情况下,使用缓存对性能的提高更明显. Mybatis缓存分为一级缓存和二级缓

  • MyBatis 延迟加载、一级缓存、二级缓存(详解)

    使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMap,resultType不具有延迟加载功能. 一.延迟加载 延迟加载已经是老生常谈的问题,什么最大化利用数据库性能之类之类的,也懒的列举了,总是我一提到延迟加载脑子里就会想起来了Hibernate get和load的区别.OK,废话少说,直接看代码. 先来修改配置项xml. 注意,编写mybatis.xm

随机推荐