Java学习-MyBatis缓存

MyBatis缓存

MyBatis一级缓存
  • 一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会去访问数据库
  • 一级缓存失效的四种情况
    • 不同的SqlSession对应不同的一级缓存
    • 同一个SqlSession但查询条件不同
    • 同一个SqlSession两次查询期间执行了任何一次增删改操作
    • 同一个SqlSession两次查询期间手动清除了缓存
  @Testpublic void testGetEmp() {SqlSession sqlSession1 = SqlSessionUtils.getSqlSession();CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);Emp emp1 = mapper1.getEmpById(4);System.out.println(emp1);//手动清空缓存sqlSession1.clearCache();Emp emp2 = mapper1.getEmpById(4);System.out.println(emp2);//执行插入操作mapper1.insertEmp(new Emp(null,"jack",23,"男","jack@qq.com"));CacheMapper mapper2 = sqlSession1.getMapper(CacheMapper.class);Emp emp3 = mapper2.getEmpById(4);System.out.println(emp3);//使用不同的SqlSessionSqlSession sqlSession2 = SqlSessionUtils.getSqlSession();CacheMapper mapper3 = sqlSession2.getMapper(CacheMapper.class);Emp emp4 = mapper3.getEmpById(4);System.out.println(emp4);}
/*①不同的SqlSession查询相同的数据缓存失效②同一个SqlSession两次查询期间执行了插入操作,导致缓存失效③同一个SqlSession两次查询期间手动清空了缓存
*/
DEBUG 06-14 14:45:16,001 ==>  Preparing: select * from t_emp where eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,021 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,048 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
DEBUG 06-14 14:45:16,048 ==>  Preparing: select * from t_emp where eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,048 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,048 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
DEBUG 06-14 14:45:16,048 ==>  Preparing: insert into t_emp(eid,emp_name,age,sex,email) values(null,?,?,?,?); (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,048 ==> Parameters: jack(String), 23(Integer),(String), jack@qq.com(String) (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,056 <==    Updates: 1 (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,056 ==>  Preparing: select * from t_emp where eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,056 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,056 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
DEBUG 06-14 14:45:16,111 ==>  Preparing: select * from t_emp where eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,111 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-14 14:45:16,127 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
MyBatis二级缓存
  • 二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存,此后再执行相同查询,结果就会从缓存中获取
  • 二级缓存开启条件:
    • 在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
    • 在映射文件中设置标签
    • 二级缓存必须在SqlSession关闭或提交之后有效
    • 查询的数据所转换的实体类型必须实现序列化的接口
//上述条件缺一不可
@Testpublic void testTwoCache() throws IOException {SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession1 = sqlSessionFactory.openSession(true);CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);System.out.println(mapper1.getEmpById(4));sqlSession1.close();SqlSession sqlSession2 = sqlSessionFactory.openSession(true);CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);System.out.println(mapper2.getEmpById(4));sqlSession2.close();}
//执行结果
DEBUG 06-14 15:23:18,059 Cache Hit Ratio [com.lotus.mybatis.mapper.CacheMapper]: 0.0 (LoggingCache.java:60) 
DEBUG 06-14 15:23:18,968 ==>  Preparing: select * from t_emp where eid=? (BaseJdbcLogger.java:137) 
DEBUG 06-14 15:23:18,984 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 06-14 15:23:19,015 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
WARN  06-14 15:23:19,015 As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66 (SerialFilterChecker.java:46) 
DEBUG 06-14 15:23:19,015 Cache Hit Ratio [com.lotus.mybatis.mapper.CacheMapper]: 0.5 (LoggingCache.java:60) 
Emp{eid=4, empName='tye', age=14, sex='男', email='tye@qq.com', dept=null}
  • 二级缓存失效情况
    • 两次查询期间执行了任何一次增删改操作,会使一级和二级缓存同时失效
二级缓存相关配置
  • 在mapper配置文件中添加的cache标签可以设置一些属性
    • eviction属性:缓存回收策略
      • LRU(Least Recently Used) :最近最少使用,移除最长时间不被使用的对象
      • FIFO(First In First Out):先进先出,按对象进入缓存的顺序来移除它们
      • SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
      • WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象
      • 默认LRU
    • flushInterval属性:刷新间隔,单位毫秒
      • 默认不设置,也就是无刷新间隔,缓存仅调用语句时刷新
    • size属性:引用数目,正整数
      • 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
    • readOnly属性:只读,true|false
      • true:只读缓存,会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,提供了很重要的性能优势
      • false:读写缓存,会返回缓存对象的拷贝(通过序列化),会慢一些,但安全,默认为false
缓存查询顺序
  • ①先查询二级缓存,二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  • ②如果二级缓存没有命中,再查询一级缓存
  • ③如果一级缓存也没有命中,则查询数据库
  • ④SqlSession关闭之后,一级缓存中的数据会导入二级缓存
整合第三方缓存EHCache
<!-- Mybatis EHCache整合 -->
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.1</version>
</dependency>
<!-- slf4j日志门面的一个具体实现 -->
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version>
</dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/27347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌重塑Transformer:无限记忆力,无限长输入,登上Nature

Infini-attention机制为Transformer在具有挑战性的长语境任务中释放出了新的能力&#xff0c;对于调整现有模型以适应长输入也非常实用。 谷歌的最新研究成果Infini-attention机制&#xff08;无限长注意力&#xff09;将内存压缩引入了传统注意力机制&#xff0c;并在单个Tra…

Github 2024-06-15Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-06-15统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目1JavaScript项目1Deno: 现代JavaScript和TypeScript运行时 创建周期:2118 天开发语言:Rust, JavaScript协议类型:M…

重装了mysql,然后安装为服务时,net start 启动一直报错,MySQL服务无法启动的解决

之前写过一篇关于安装mysql的文章&#xff0c;按上面的处理&#xff0c;基本上是可以的。 今天换了下目录&#xff0c;重新安装&#xff0c;一直报错。 然后我们来看一下问题&#xff1a; mysqld -console 这里的目录是有问题的&#xff0c;设置的是&#xff1a;datadird:\to…

个人关于Leecode 49题见解(保姆级)

题目&#xff1a; 49. 字母异位词分组 中等 相关标签 相关企业 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "…

对用户体验的一些思考

任何产品最终的形态&#xff0c;某种意义上来说&#xff0c;成功的标准无非就是以最小的成本&#xff0c;创造出最大的利润&#xff0c;盈利才是最终目的。这也就是说&#xff0c;我们做的产品应该顾及买家的感受&#xff0c;即顾客的感受&#xff0c;这被称为“用户体验”。 用…

React框架资源

React框架资源可以从多个方面获取&#xff0c;包括官方文档、教程、书籍、社区等。以下是一些React框架资源的清晰分点和归纳&#xff1a; 官方文档 新官方文档&#xff1a;React在2023年3月发布了全新的官方文档&#xff0c;位于https://react.dev/​。新文档包含教程、指南…

AI助力密码安全:利用机器学习提升密码安全性

信息安全已经成为了当今数字世界的一个核心问题&#xff0c;随着互联网技术使用场景的不断增加&#xff0c;创建和管理安全的密码已经成为了保证在线账户安全的关键要求。本文将研究和探讨如何利用人工智能&#xff08;AI&#xff09;和机器学习技术来提升密码的安全性。 学习目…

「前端+鸿蒙」鸿蒙应用开发-ArkTS语法说明-自定义组件

ArkTS 是鸿蒙(HarmonyOS)应用开发中的一个现代框架,它允许开发者以 TypeScript 的方式来创建和管理 UI 组件。以下是使用 ArkTS 创建自定义组件的基本语法说明和示例代码。 ArkTS 快速入门 - 语法说明 - 自定义组件 定义组件类 自定义组件通常是通过继承 Component 类来定…

GraphQL(9):Spring Boot集成Graphql简单实例

1 安装插件 我这边使用的是IDEA&#xff0c;需要先按照Graphql插件&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09;打开插件管理 在IDEA中&#xff0c;打开主菜单&#xff0c;选择 "File" -> "Settings" (或者使用快捷键 Ctrl Alt S …

运算符有哪些?优先级是怎么样的?转换数据类型的方法?(最少4种)

算术运算符&#xff1a; &#xff08;加法&#xff09;-&#xff08;减法&#xff09;*&#xff08;乘法&#xff09;/&#xff08;除法&#xff09;%&#xff08;取模&#xff0c;返回除法的余数&#xff09;&#xff08;自增&#xff09;--&#xff08;自减&#xff09; 赋…

【Qt】xml文件节点读取

1. xml文件 test.xml 文件内容 <?xml version"1.0" encoding"utf-8"?> <library><book1><id>00000001</id><name>1111</name></book1> </library>2. 代码 void DataXml::read() {//打开文件QF…

linux man使用

安装 man-db 提供了 man 命令&#xff0c;less 是 man 的默认分页器。 man-pages 提供了 Linux man 页面的内容。 对于中文可以使用&#xff1a; manpages-zh gnome 桌面下可以使用 gnome-help查询 使用 通过以下命令阅读man手册页&#xff1a; man手册页分为很多段落。…

简说安全分析

安全分析的目的 识别并解决安全漏洞&#xff1a;通过安全分析&#xff0c;可以识别系统、网络或应用程序中的安全漏洞&#xff0c;并提供相应的修复措施&#xff0c;以减少安全威胁。评估安全风险&#xff1a;安全分析帮助组织评估潜在的安全风险&#xff0c;并提供建议和措施…

11.3 Go 标准库的使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

智能合约中权限管理不当

权限管理不当 &#xff1a; 权限管理不当是智能合约中常见的安全问题之一&#xff0c;尤其是在管理员或特定账户被过度赋予权限的情况下。如果合约中的关键功能&#xff0c;如转移资产、修改合约状态或升级合约逻辑&#xff0c;可以被未经授权的实体随意操作&#xff0c;这将构…

实体类status属性使用枚举类型的步骤

1. 问题引出 当实体类的状态属性为Integer类型时&#xff0c;容易写错 2. 初步修改 把状态属性强制为某个类型&#xff0c;并且自定义一些可供选择的常量。 public class LessonStatus {public static final LessonStatus NOT_LEARNED new LessonStatus(0,"未学习"…

QT打包(windows linux)封包 完整图文版

目录 简介: 一. for windows 1.首先下载组件 2.开始构建Release版本. 3.然后点击构建 4.在文件夹内直接点击exe文件,会报下面的错误,因为缺少dll连接; 5.需要把这个exe单独复制到一个文件夹内, 6.先cd到单独exe所在的文件夹; cd 文件路径 7.然后运行 windeployqt 文…

结构型模式-装饰模式

装饰模式是什么 装饰模式是一种结构型设计模式&#xff0c;它允许你向一个对象添加新的功能&#xff0c;而无需修改原始类的代码。通过将对象包装在一个装饰器类中&#xff0c;你可以在运行时动态地添加、修改或删除对象的行为。 装饰模式基于组合而非继承的原则&#xff0c;它…

KIVY Tutorials » Pong Game Tutorial¶

1Pong Game Tutorial — Kivy 2.3.0 documentation Introduction Welcome to the Pong tutorial 欢迎来到 乒乓球 导师辅导课 This tutorial will teach you how to write pong using Kivy. We’ll start with a basic application like the one described in the Create …

笔记100:使用 OSQP-Eigen 对 MPC 进行求解的方法与代码

1. 前言&#xff1a; 我们在对系统进行建模的时候&#xff0c;为了减少计算量&#xff0c;一般都将系统简化为线性的&#xff0c;系统如果有约束&#xff0c;也是将约束简化为线性的&#xff1b; 因此本篇博客只针对两种常见系统模型的 MPC 问题进行求解&#xff1a; 线性系统…