mybatis一级缓存(session cache)引发的问题
2023-09-14 09:03:16 时间
最近项目功能单元测试中,出现了一个奇怪的bug。远程调试发现,程序进行了2次相同的查询,返回了实体类(ClassA)的2个对象:classAInstance1和classAInstance2,当修改classAInstance1.property1时,竟然classAInstance2.property1也被改了!!! 很快发现classAInstan
Mybatis的一级缓存和二级缓存的理解以及用法 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。
Java Spring Boot开发实战系列课程【第6讲】:Spring Boot 2.0实战MyBatis与优化(Java面试题) 立即下载
最近项目功能单元测试中,出现了一个奇怪的bug。远程调试发现,程序进行了2次相同的查询,返回了实体类(ClassA)的2个对象:classAInstance1和classAInstance2,当修改classAInstance1.property1时,竟然classAInstance2.property1也被改了!!! 很快发现classAInstance1和classAInstance2地址是相同的,它们是同一个内存对象!
经调试发现,mybatis返回的实体类的内存地址是相同的!于是猜测是mybatis缓存的原因,于是进行了下面的测试验证。
经过单元测试验证,不开启事务的情况下,多次相同的查询,返回对象地址不相等, 代码略。
经过单元测试验证,在一个事务内,多次相同的查询,返回对象地址相等, 代码如下:
@Resource private MybatisSessionCacheTestService mybatisSessionCacheTestService; @Test public void test_mybatis_sql_session_cache(){ Long id = 100L; ClassA classAInstance1 = mybatisSessionCacheTestService.queryById(id); ClassA classAInstance2 = mybatisSessionCacheTestService.queryById(id); //assert mybatis cache is on Assert.assertTrue(classAInstance1 == classAInstance2); }
@Service public class MybatisSessionCacheTestService { @Resource private ClassADAO classDAO; @Transactional //spring 事务注解 public ClassA queryById(Long id){ return classADAO.queryById(id); }1.把查询提前到事务之前(之外),这样只解决了个别问题,解决并不彻底。 2.在mybatis的mapper xml里配置每次清空缓存flushCache:
select id="selectById" resultType="ClassA" flushCache="true" /select附录:mybatis缓存介绍
即session缓存,作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空,默认开启。
注意 集成spring(使用mybatis-spring)时:
每次查询spring会重新创建SqlSession,所以一级缓存是不生效的。 而当开启事务时,spring会使用同一个SqlSession做查询,所以这个情况下一级缓存是生效的Mybatis的一级缓存和二级缓存的理解以及用法 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。
Java Spring Boot开发实战系列课程【第6讲】:Spring Boot 2.0实战MyBatis与优化(Java面试题) 立即下载
相关文章
- mybatis的缓存策略
- MyBatis缓存特性详解
- SpringBoot之Mybatis操作中使用Redis做缓存
- springboot整合mybatis的两种方式
- Spring+Mybatis+SpringMVC+Maven+MySql搭建实例
- MyBatis 缓存
- 项目总结2——mybatis配置的理解
- 自定义MyBatis
- mybatis insert foreach循环插入
- spring boot整合mybatis+通用mapper+pagehelper分页插件
- Mybatis 3学习笔记(一)
- 【mybatis4】MyBatis的一级缓存机制
- Mybatis缓存
- java-mybaits-014-数据库缓存设计【querycache、mybatis一级缓存、二级缓存】
- Mybatis源码分析之(一)搭建一个mybatis框架(写一个mybatis的Demo)
- mybatis中的#{}和${}区别,和使用场景