mybatis中的缓存问题解析
发布时间 - 2026-01-11 00:40:01 点击率:次关于mybatis基础我们前面几篇博客已经介绍了很多了,今天我们来说一个简单的问题,那就是mybatis中的缓存问题。mybatis本身对缓存提供了支持,但是如果我们没有进行任何配置,那么默认情况下系统只开启了一级缓存,一级缓存就是同一个SqlSession执行的相同查询是会进行缓存的,OK,那么今天我们就来看看这些缓存,并简单验证下。

系统默认开启了一级缓存
这个缓存系统默认情况下是开启的,当我们获取到一个SqlSession对象之后,如果调用SqlSession中的同一个方法查询同一条数据,那么第二次查询将不会去数据库中查询,因为第一次查询有缓存,直接调用缓存数据即可,除非缓存超时或者我们明确声明数据要刷新,否则都是直接调用缓存数据。OK,我们来看一个简单的案例。
查询代码如下:
SqlSession sqlSession = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询同一条数据时会缓存
User user = mapper.getUser(1l);
User user2 = mapper.getUser(1l);
System.out.println(user.toString());
System.out.println(user2.toString());
sqlSession.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
我们来看看日志:
小伙伴们看到,我这里执行了两次查询,但实际上只执行了一次SQL语句。
自己配置二级缓存
上面的缓存是由系统默认配置的,这个有一定的局限性,就是只能在同一个SqlSession中有效,脱离了同一个SqlSession就没法使用这个缓存了,有的时候我们可能希望能够跨SqlSession进行数据缓存。那么这个时候需要我们进行手动开启二级缓存。
二级缓存的开启方式其实很简单,只需要我们在userMapper.xml中配置<cache/>节点即可。如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.sang.db.UserMapper">
<cache/>
<select id="getUser" resultType="org.sang.bean.User" parameterType="Long">
select * from user where id = #{id}
</select>
<insert id="insertUser" parameterType="org.sang.bean.User">
INSERT INTO user(username,password,address) VALUES (#{username},#{password},#{address})
</insert>
<delete id="deleteUser" parameterType="Long">
DELETE FROM user where id=#{id}
</delete>
<select id="getAll" resultType="u">
SELECT * from user
</select>
</mapper>
这样简单配置之后,二级缓存就算开启了,这样的配置中,许多东西都是默认的,比如所有的select语句都会被缓存,所有的delete、insert和update则都会将缓存刷新,还比如缓存将使用LRU算法进行内存回收等。那么这些东西如果需要配置的话,我们可以按如下方式进行配置:
<cache eviction="LRU" flushInterval="20000" size="1024" readOnly="true"/>,这里的eviction表示缓存策略,除了LRU之外还有先进先出(FIFO)、软引用(SOFT)、弱引用(WEAK)等,flushInterval则表示刷新时间,表示缓存的对象个数,readOnly为true则表示缓存只可以读取不可以修改。
OK,做了如上配置之后还不够,开启二级缓存还要求我们的实体类可以序列化,实现Serializable接口即可,如下:
public class User implements Serializable{
private Long id;
private String username;
private String password;
private String address;
...
}
如此之后,我们的二级缓存就算成功开启了,OK,我么来测试下:
SqlSession sqlSession = null;
SqlSession sqlSession2 = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUser(1l);
System.out.println(user.toString());
sqlSession.commit();
sqlSession2 = DBUtils.openSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUser(1l);
System.out.println(user2.toString());
sqlSession2.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
sqlSession2.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
if (sqlSession2 != null) {
sqlSession2.close();
}
}
打印日志如下:
OK,小伙伴们看到SQL语句实际上只执行了一次。
OK,以上就是对mybatis中缓存的一个简单介绍。
本文案例下载: 本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis8
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# mybatis
# 缓存
# 缓存问题
# mybatis缓存配置
# 【MyBatis源码全面解析】MyBatis一二级缓存介绍
# 深入理解MyBatis中的一级缓存与二级缓存
# mybatis二级缓存默认未开启源码的问题
# 都是
# 开启了
# 上只
# 情况下
# 直接调用
# 小伙伴们
# 是由
# 不可以
# 两次
# 有一定
# 我们可以
# 来看看
# 这个时候
# 只需要
# 当我们
# 就来
# 会去
# 还不够
# 将不
# 会将
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
常州企业网站制作公司,全国继续教育网怎么登录?
微信小程序 input输入框控件详解及实例(多种示例)
如何登录建站主机?访问步骤全解析
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
Android自定义控件实现温度旋转按钮效果
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
如何确保FTP站点访问权限与数据传输安全?
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
Laravel如何处理CORS跨域请求?(配置示例)
浅谈redis在项目中的应用
JavaScript如何实现错误处理_try...catch如何捕获异常?
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
原生JS实现图片轮播切换效果
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
如何在阿里云购买域名并搭建网站?
如何在万网ECS上快速搭建专属网站?
如何在万网利用已有域名快速建站?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
JS弹性运动实现方法分析
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
如何批量查询域名的建站时间记录?
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
如何快速生成可下载的建站源码工具?
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
Android仿QQ列表左滑删除操作
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
如何在 Pandas 中基于一列条件计算另一列的分组均值
JavaScript常见的五种数组去重的方式
昵图网官方站入口 昵图网素材图库官网入口
javascript日期怎么处理_如何格式化输出
Laravel如何自定义分页视图?(Pagination示例)
Laravel如何使用Livewire构建动态组件?(入门代码)
如何在Windows环境下新建FTP站点并设置权限?
Laravel如何与Inertia.js和Vue/React构建现代单页应用
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
黑客如何利用漏洞与弱口令入侵网站服务器?
音乐网站服务器如何优化API响应速度?
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤

