MyBatis 中如何使用缓存

MyBatis 中如何使用缓存

MyBatis 是一个基于 Java 的持久层框架,它提供了多种方式来使用缓存,包括一级缓存和二级缓存。本文将介绍 MyBatis 中常见的缓存使用方式及其使用方法。

在这里插入图片描述

1. 一级缓存

MyBatis 中的一级缓存是指 SqlSession 的缓存,它默认是开启的。在同一个 SqlSession 中,如果执行了相同的 SQL 语句,那么 MyBatis 会从缓存中读取结果,而不是再次向数据库发起请求。下面是一个简单的示例:

public class MyBatisTest {public static void main(String[] args) {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();try {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 第一次查询,从数据库中获取数据User user1 = userMapper.getUserById(1);System.out.println(user1);// 第二次查询,从一级缓存中获取数据User user2 = userMapper.getUserById(1);System.out.println(user2);// 更新数据,清空一级缓存user1.setName("Tom");userMapper.updateUser(user1);sqlSession.commit();// 第三次查询,从数据库中获取数据User user3 = userMapper.getUserById(1);System.out.println(user3);// 第四次查询,从一级缓存中获取数据User user4 = userMapper.getUserById(1);System.out.println(user4);} finally {sqlSession.close();}}
}

在上面的示例代码中,首先读取了配置文件 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 将配置文件解析为 SqlSessionFactory 对象,最后通过 SqlSessionFactory 创建 SqlSession 对象。在 SqlSession 中,通过 getMapper 方法获取映射器接口的实例,然后就可以直接调用映射器接口中的方法执行 SQL 语句了。在第一次查询时,会从数据库中获取数据,并将结果存储在一级缓存中。在第二次查询时,会直接从一级缓存中获取数据。在更新数据后,需要清空一级缓存,否则会出现数据不一致的情况。

2. 二级缓存

除了一级缓存外,MyBatis 还提供了二级缓存,它是 SqlSessionFactory 的缓存。在多个 SqlSession 中共享同一个二级缓存,如果执行了相同的 SQL 语句,那么 MyBatis 会从缓存中读取结果,而不是再次向数据库发起请求。下面是一个简单的示例:

public class MyBatisTest {public static void main(String[] args) {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();try {UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);// 第一次查询,从数据库中获取数据,并存储到二级缓存中User user1 = userMapper1.getUserById(1);System.out.println(user1);// 第二次查询,从二级缓存中获取数据User user2 = userMapper2.getUserById(1);System.out.println(user2);// 更新数据,清空二级缓存user1.setName("Tom");userMapper1.updateUser(user1);sqlSession1.commit();// 第三次查询,从数据库中获取数据,并存储到二级缓存中User user3 = userMapper2.getUserById(1);System.out.println(user3);// 第四次查询,从二级缓存中获取数据User user4 = userMapper1.getUserById(1);System.out.println(user4);} finally {sqlSession1.close();sqlSession2.close();}}
}

在上面的示例代码中,首先读取了配置文件 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 将配置文件解析为 SqlSessionFactory 对象,最后通过 SqlSessionFactory 创建 SqlSession 对象。在 SqlSession 中,通过 getMapper 方法获取映射器接口的实例,在多个 SqlSession 中共享同一个二级缓存。在第一次查询时,会从数据库中获取数据,并将结果存储在二级缓存中。在第二次查询时,会直接从二级缓存中获取数据。在更新数据后,需要清空二级缓存,否则会出现数据不一致的情况。

要启用二级缓存,需要在配置文件 mybatis-config.xml 中进行配置。下面是一个简单的配置示例:

<configuration><settings><setting name="cacheEnabled" value="true"/></settings><typeAliases><typeAlias type="com.example.User" alias="User"/></typeAliases><mappers><mapper resource="com/example/UserMapper.xml"/></mappers><cache type="org.apache.ibatis.cache.impl.PerpetualCache"/>
</configuration>

在上面的配置文件中,首先开启了缓存功能,然后定义了一个类型别名 User,最后定义了一个缓存实现类 org.apache.ibatis.cache.impl.PerpetualCache。

3. 自定义缓存

除了使用 MyBatis 提供的缓存实现类以外,还可以自定义缓存实现类。下面是一个简单的自定义缓存实现类示例:

public class MyCache implements Cache {private final String id;private final Map<Object, Object> cache = new HashMap<>();public MyCache(String id) {this.id = id;}@Overridepublic String getId() {return id;}@Overridepublic void putObject(Object key, Object value) {cache.put(key, value);}@Overridepublic Object getObject(Object key) {return cache.get(key);}@Overridepublic Object removeObject(Object key) {return cache.remove(key);}@Overridepublic void clear() {cache.clear();}@Overridepublic int getSize() {return cache.size();}@Overridepublic ReadWriteLock getReadWriteLock() {return null;}
}

在上面的示例代码中,实现了 MyBatis 的 Cache 接口,使用了一个 HashMap 作为缓存实现。

要使用自定义缓存,需要在配置文件 mybatis-config.xml 中进行配置。下面是一个简单的配置示例:

<configuration><settings><setting name="cacheEnabled" value="true"/></settings><typeAliases><typeAlias type="com.example.User" alias="User"/></typeAliases><mappers><mapper resource="com/example/UserMapper.xml"/></mappers><cache type="com.example.MyCache"><property name="id" value="myCache"/></cache>
</configuration>

在上面的配置文件中,首先开启了缓存功能,然后定义了一个类型别名 User,最后定义了一个缓存实现类 com.example.MyCache,并指定了缓存实现类的 id。如果没有指定 id,则默认使用缓存实现类的类名作为 id。

结论

MyBatis 提供了多种方式来使用缓存,包括一级缓存和二级缓存。一级缓存是 SqlSession 的缓存,它默认是开启的。二级缓存是 SqlSessionFactory 的缓存,需要在配置文件中进行配置。除了使用 MyBatis 提供的缓存实现类以外,还可以自定义缓存实现类。在使用缓存时,需要注意清空缓存,否则会出现数据不一致的情况。

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

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

相关文章

2023机器人操作系统(ROS)暑期学校预热-线下时间/地点-(转发)

原文地址&#xff1a; https://mp.weixin.qq.com/s/McjBgCpecL6OMgpcrPyY_Q 中国机器人操作系统&#xff08;ROS&#xff09;暑期学校自2015年举办以来&#xff0c;被中国机器人业界和学界&#xff0c;以及ROS开源基金会誉为除了ROSCon之外规模最大、参与人数最多、最成功的RO…

【JAVA】与数字相关的类,Number Math 类

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言数据类型Number类介绍数据格式化实例 Math类介绍静态常量实例 前言 为了解决对数字、日期和系统设置进行处理的困难&#xff0c;如&#xff1a;一些数字&数学问题、随机…

React中 Real DOM 和 Virtual DOM 的区别?优缺点?

一、是什么 Real DOM&#xff0c;真实 DOM&#xff0c;意思为文档对象模型&#xff0c;是一个结构化文本的抽象&#xff0c;在页面渲染出的每一个结点都是一个真实 DOM 结构&#xff0c;如下&#xff1a; Virtual Dom&#xff0c;本质上是以 JavaScript 对象形式存在的对 DOM …

【Visual Studio】在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 编号内容1【Visual Studio】在 Windows 上使用 Visual Studio 构建 VTK2【Visual Studio】在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK3【VTK】VTK 显…

OpenCv色彩空间

目录 一、RGB 二、图像处理入门 三、色彩空间的转换 一、RGB 在表示图像时&#xff0c;有多种不同的颜色模型&#xff0c;但最常见的是红、绿、蓝(RGB) 模型RGB 模型是一种加法颜色模型&#xff0c;其中原色 (在RGB模型中&#xff0c;原色是红色 R、绿色 G 和蓝色 B)混合在…

打工人如何利用自动化实现职场突围

作为优秀的打工人&#xff0c;如果可以将办公中的重复性、繁琐性、低效性工作自动化&#xff0c;那么将省去许多日常工作。许亚宁就是这样一个优秀的打工人&#xff0c;善于使用各类自动化工具来提升工作效率&#xff0c;上周的直播他分享了如何利用自动化工具&#xff0c;实现…

Qt,day4

闹钟 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);this->setWindowTitle("闹钟");this->setWindowIcon(QIcon("D:\\HQYJRJ\\QT\\day1\\…

运输层(TCP运输协议相关)

运输层 1. 运输层概述2. 端口号3. 运输层复用和分用4. 应用层常见协议使用的运输层熟知端口号5. TCP协议对比UDP协议6. TCP的流量控制7. TCP的拥塞控制7.1 慢开始算法、拥塞避免算法7.2 快重传算法7.3 快恢复算法 8. TCP超时重传时间的选择8.1 超时重传时间计算 9. TCP可靠传输…

Linux中ssh登陆慢的两种原因

useDNS配置导致登陆慢 如果ssh server的配置文件&#xff08;通常是 /etc/ssh/sshd_config &#xff09;中设置 useDNS yes &#xff0c;可能会导致 ssh 登陆卡住几十秒。将该配置项设为 no&#xff0c;然后重启 ssh 服务&#xff0c;再次登陆就恢复正常。将useDND配置为yes会…

Camtasia Studio 2023 最新中文版,camtasiaStudio如何添加背景音乐

Camtasia2023的视频编辑工具可以帮助用户剪辑、裁剪、旋转、调整大小、添加特效、混合音频等。用户还可以使用Camtasia2023的字幕功能添加字幕和注释&#xff0c;以及使用其内置的特效和转场来提高视频的视觉效果。 Camtasia Studio 2023新功能介绍 的光标增强 由于光标在屏幕…

容器化背后的魔法之Docker底层逻辑解密

Docker内部工作原理是怎样的&#xff1f; 现在我们知道了Docker是什么以及它提供了哪些好处&#xff0c;让我们逐个重要的细节来了解。 什么是容器&#xff1f;它们是如何工作的&#xff1f; 在深入研究Docker的内部机制之前&#xff0c;我们首先要了解容器的概念。简单地说…

解密Prompt系列4. 升级Instruction Tuning:Flan/T0/InstructGPT/TKInstruct

这一章我们聊聊指令微调&#xff0c;指令微调和前3章介绍的prompt有什么关系呢&#xff1f;哈哈只要你细品&#xff0c;你就会发现大家对prompt和instruction的定义存在些出入&#xff0c;部分认为instruction是prompt的子集&#xff0c;部分认为instruction是句子类型的prompt…