当前位置: 首页 > news >正文

Mybatis行为配置之Ⅰ—缓存

专栏精选

引入Mybatis

Mybatis的快速入门

Mybatis的增删改查扩展功能说明

mapper映射的参数和结果

Mybatis复杂类型的结果映射

Mybatis基于注解的结果映射

Mybatis枚举类型处理和类型处理器

再谈动态SQL

Mybatis配置入门

Mybatis行为配置之Ⅰ—缓存

Mybatis行为配置之Ⅱ—结果相关配置项说明

Mybatis行为配置之Ⅲ—其他行为配置项说明

Mybatis行为配置之Ⅳ—日志

Mybatis整合Spring详解

Mybatis插件入门

Mybatis专栏代码资源

文章目录

  • 专栏精选
  • 摘要
  • 引言
  • 正文
    • 缓存配置项说明
      • cacheEnabled
      • localCacheScope
    • 一级缓存
    • 二级缓存
  • 总结

摘要

在这篇文章中,我们将进入Mybatis行为配置的世界,了解Mybatis一二级缓存的基本方法,其中的很多观点或内容都能在一定程度上让我们的开发之旅更加轻松方便,这是一个菜鸟提升技术能力,老鸟巩固基础知识的好机会。准备好开启今天的神奇之旅了吗?

引言

大家好,我是奇迹老李,一个专注于分享开发经验和基础教程的博主。欢迎来到我的频道,这里汇聚了汇集编程技巧、代码示例和技术教程,欢迎广大朋友们点赞评论提出意见,重要的是点击关注喔 🙆,期待在这里与你共同度过美好的时光🕹️。今天要和大家分享的内容是Mybatis行为配置之缓存。做好准备,Let’s go🚎🚀

正文

首图

在Mybatis 的配置文件中 <setting>标签用于配置Mybatis项目执行过程中的行为,这些行为配置项每一个都对应 Configuration类中的一个属性, Configuration类也为这些属性提供了setter方法,除了使用配置文件之外,我们还可以通过调用这些方法来完成相应的配置。当然,这些行为配置项Mybatis大都有默认的配置,默认配置在Mybatis的源码中 org.apache.ibatis.builder.xml.XMLConfigBuilder类的 settingsElement方法中定义,可自行查看

缓存配置项说明

cacheEnabled

备注:是否开启二级缓存
默认值:true
建议值:false
建议原因:
mybatis缓存包括一级缓存和二级缓存,一级缓存是不能关闭的(可以通过配置修改作用域),二级缓存可以通过此配置关闭。关于一二级缓存的详细内容,见[[Mybatis缓存]]
在集群/微服务环境下,其他服务修改了同一个文件对当前微服务是不可见的,在这种情况下,数据库里的真实数据已经更新了,但当前服务的缓存仍然在生效中,会读取到脏数据。

localCacheScope

备注:设置一级缓存作用域
默认值:SESSION
建议值:STATEMENT
建议原因:微服务环境下可以防止读取到脏数据。

下面介绍一二级缓存的详细说明

一级缓存

mybatis的一级缓存提供SqlSession级别的查询结果缓存,也就是说在同一个SqlSession中,如果没有进行过增删改操作,相同条件的sql查询会通过一级缓存查询结果,而不用反复通过数据库执行sql。

一级缓存是全局开启的,只能通过localCacheScope这个配置修改一级缓存的作用域,可选的配置包括:

可选项是否默认值说明
SESSIONyes缓存作用在session级别,同一个SqlSession中共享
STATEMENTno缓存作用在一个查询级别

可以通过在一个sqlSession中反复进行同一个查询的方式验证一级缓存。

测试代码如下:

public class EnvConfigTest {  private SqlSessionFactory sqlSessionFactory;  @Before  public void before() {  try (InputStream input = EnvConfigTest.class.getResourceAsStream("/mybatis-config.xml")) {  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();  sqlSessionFactory = builder.build(input);  } catch (IOException e) {  throw new RuntimeException(e);  }  }@Test  public void testSessionCache(){  SqlSession session = this.sqlSessionFactory.openSession();  ApplicationRepository mapper = session.getMapper(ApplicationRepository.class);  AppTestEntity e1 = mapper.queryById(2L);  AppTestEntity e2 = mapper.queryById(2L);  System.out.println("boolean(e1=e2) is "+(e1==e2));  session.close();  }
}

设置<setting name="localCacheScope" value="SESSION"/>时的打印结果为:

boolean(e1=e2) is true

设置<setting name="localCacheScope" value="STATEMENT"/> 时的打印结果为:

boolean(e1=e2) is false

可以看出,STATEMENT作用域的作用范围就是一次sql查询,也就时变相的关闭了Mybatis的一级缓存。而SESSION作用域会在同一个 sqlSession内部共享查询结果。

刷新一级缓存的方法有两种

  1. 在两次查询之间进行一次增删改操作
  2. 通过 SqlSession#clearCache 方法清空缓存

测试清空缓存

    @Test  public void testSessionCache(){  SqlSession session = this.sqlSessionFactory.openSession();  ApplicationRepository mapper = session.getMapper(ApplicationRepository.class);  AppTestEntity e1 = mapper.queryById(2L);  session.clearCache();  AppTestEntity e2 = mapper.queryById(2L);  System.out.println("boolean(e1=e2) is "+(e1==e2));  session.close();  }

配置<setting name="localCacheScope" value="SESSION"/>时的打印结果为:

boolean(e1=e2) is false

二级缓存

Mybatis的二级缓存可是实现在多个SqlSession中共享,默认是开启的,可以通过 <setting name="cacheEnabled" value="false"/>这个配置项关闭。二级缓存的作用域是一个namespace,即mapper映射文件中的namespace。

可以通过在两个 SqlSession 中查询同一内容的方式验证二级缓存是否生效。测试代码为:

public class EnvConfigTest {  private SqlSessionFactory sqlSessionFactory;//省略@Before@Test  public void testCacheFirst() {  SqlSession session1 = this.sqlSessionFactory.openSession();  ApplicationRepository mapper1 = session1.getMapper(ApplicationRepository.class);  SqlSession session2 = this.sqlSessionFactory.openSession();  ApplicationRepository mapper2 = session2.getMapper(ApplicationRepository.class);  System.out.println("==session1查询==");  AppTestEntity e1 = mapper1.queryById(1L);  //提交事务,使二级缓存生效session1.commit();  System.out.println("==session2查询==");  AppTestEntity e2 = mapper2.queryById(1L);  System.out.println("boolean(session1_e1=session2_e2) is "+(e1==e2));  session1.close();  session2.close();  }
}

配置 <setting name="cacheEnabled" value="false"/>时的效果

==session1查询==
==session2查询==
boolean(session1_e1=session2_e2) is false

配置 <setting name="cacheEnabled" value="true"/>或不配置时的效果

==session1查询==
==session2查询==
boolean(session1_e1=session2_e2) is true

这里需要注意一点,要使二级缓存生效,需要在查询条件后提交事务(或者通过框架控制事务执行,如Spring中的@Transicational注解),如果没有提交事务也不会走二级缓存。如果注释掉测试代码中的 session1.commit();一行,打印结果为:

==session1查询==
==session2查询==
boolean(session1_e1=session2_e2) is false

总结

在这片文章中我们介绍了Mybatis中缓存的配置,以及如何确定一个查询是否走了缓存。Mybatis的缓存分为一级缓存和二级缓存,一二级缓存都是默认开启的,其中二级缓存可以通过配置关闭,而一级缓存是不能关闭的,只能通过配置修改一级缓存的作用域。


📩 联系方式
邮箱:qijilaoli@foxmail.com

❗版权声明
本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问奇迹老李的博客首页

相关文章:

  • 【北亚数据恢复】mysql表被truncate,表数据被delete的数据恢复案例
  • Python 爬虫 教程
  • 阿里后端实习一面面经
  • 【javaweb】tomcat9.0中的HttpServlet
  • 排序算法-选择插入排序
  • WSL使用VsCode运行cpp文件
  • 【VUE】Flask+vue-element-admin前后端分离项目发布到linux服务器操作指南
  • PyTorch常用工具(2)预训练模型
  • 2022年山东省职业院校技能大赛高职组云计算赛项试卷第三场-公有云
  • 雪花算法(Snowflake)介绍和Java实现
  • 微信小程序有几个文件
  • LVS那点事
  • 易舟云财务软件使用教程【文章目录】
  • 题目 1669: 求圆的面积
  • Quartus的Signal Tap II的使用技巧
  • SegmentFault for Android 3.0 发布
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • [译]如何构建服务器端web组件,为何要构建?
  • avalon2.2的VM生成过程
  • Laravel Telescope:优雅的应用调试工具
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • spring-boot List转Page
  • 翻译:Hystrix - How To Use
  • 利用jquery编写加法运算验证码
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (vue)页面文件上传获取:action地址
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (强烈推荐)移动端音视频从零到上手(上)
  • (四)Android布局类型(线性布局LinearLayout)
  • (转)Android学习笔记 --- android任务栈和启动模式
  • ./configure,make,make install的作用(转)
  • .htaccess配置常用技巧
  • .net CHARTING图表控件下载地址
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .Net MVC4 上传大文件,并保存表单
  • .NET 事件模型教程(二)
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • 。Net下Windows服务程序开发疑惑
  • @angular/cli项目构建--http(2)
  • @Pointcut 使用
  • @RequestMapping 的作用是什么?
  • @Resource和@Autowired的区别
  • @TableId注解详细介绍 mybaits 实体类主键注解