赞
踩
本文主要介绍在 SpringBoot 项目中如何使用 Mybatis 的一级、二级缓存, 为了演示方便,本文的数据库采用 H2 内存数据库,数据库连接池默认使用 SpringBoot2.X 自带的 hikariCP。
正确的使用 Mybatis 缓存可以有效减少多余的数据库查询操作,节约 IO。
接下来我们从实践出发,看一看 mybatis 的一级,二级缓存如何使用,相关代码请查阅:https://github.com/zhengxl5566/springboot-demo.git
默认情况下,mybatis 开启并使用了一级缓存。
单元测试用例:
/**
* 开启事务,测试一级缓存效果
* 缓存命中顺序:二级缓存---> 一级缓存---> 数据库
**/
@Test
@Transactional(rollbackFor = Throwable.class)
public void testFistCache(){
// 第一次查询,缓存到一级缓存
userMapper.selectById(1);
// 第二次查询,直接读取一级缓存
userMapper.selectById(1);
}
执行结果:
可以看到,虽然进行了两次查询,但最终只请求了一次数据库,第二次查询命中了一级缓存,直接返回了数据。
这里有两点需要说明一下:
1、为什么开启事务
由于使用了数据库连接池,默认每次查询完之后自动 commite,这就导致两次查询使用的不是同一个 sqlSessioin,根据一级缓存的原理,它将永远不会生效。
当我们开启了事务,两次查询都在同一个 sqlSession 中,从而让第二次查询命中了一级缓存。读者可以自行关闭事务验证此结论。
2、两种一级缓存模式
一级缓存的作用域有两种:session(默认)和 statment,可通过设置 local-cache-scope 的值来切换,默认为 session。
二者的区别在于 session 会将缓存作用于同一个 sqlSesson,而 statment 仅针对一次查询,所以,local-cache-scope: statment 可以理解为关闭一级缓存。
默认情况下,mybatis 打开了二级缓存,但它并未生效,因为二级缓存的作用域是 namespace,所以还需要在 Mapper.xml 文件中配置一下才能使二级缓存生效
<cache></cache>
单元测试用例:
/**
* 测试二级缓存效果
* 需要*Mapper.xml开启二级缓存
**/
@Test
public void testSecondCache(){
userMapper.selectById(1);
userMapper.selectById(1);
}
执行结果:
这里可以看到,第二次查询直接命中了缓存,日志还打印了该缓存的命中率。读者可以自行关闭二级缓存查看效果,通过注掉对应 mapper.xml 的 cache 标签,或者 cache-enabled: false 均可
<cache></cache>
userMapper.xml
<cache-ref namespace="com.zhengxl.mybatiscache.mapper.UserOrderMapper"/>
单元测试用例:
/** * 测试多表联查的二级缓存效果 * 需要*Mapper.xml设定引用空间 **/ @Test public void testJoin(){ System.out.println(userMapper.selectJoin()); System.out.println(userMapper.selectJoin()); UserOrder userOrder = new UserOrder(); userOrder.setGoodName("myGoods"); userOrder.setUserId(1); userOrderMapper.saveOrder(userOrder); System.out.println(userMapper.selectJoin()); }
执行结果:
首先查询了两次 user 表,第二次命中二级缓存,然后更新 user_order 表,使缓存失效,第三次查询时命中数据库。
mybatis 默认的 session 级别一级缓存,由于 springboot 中默认使用了 hikariCP,所以基本没用,需要开启事务才有用。但一级缓存作用域仅限同一 sqlSession 内,无法感知到其他 sqlSession 的增删改,所以极易产生脏数据
二级缓存可通过 cache-ref 让多个 mapper.xml 共享同一 namespace,从而实现缓存共享,但多表联查时配置略微繁琐。
所以生产环境建议将一级缓存设置为 statment 级别(即关闭一级缓存),如果有必要,可以开启二级缓存
原文:https://www.cnblogs.com/zhengxl5566/p/11868656.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。