MyBatis多次查询返回相同的对象BUG解决

目录

一、问题描述

二、问题原因

三、解决方案

3.1、去除@Transactional这个注解(不推荐)

3.2、使用sqlSession.clearCache()方法(推荐)


一、问题描述

多次查询相同的数据库记录,但每次查询返回的对象是同一个实例的引用,例如Demo示例:

@SpringBootTest
class MybatisApplicationTests {

    @Resource
    private UserMapper userMapper;

    @Test
    @Transactional
    void contextLoads() {
        User user = userMapper.selectUserByUsername("张三");
        user.setUsername("李四");
        User user2 = userMapper.selectUserByUsername("张三");
        Date date = new Date();
    }

}

执行结果:

张三的原密码是123456,我想把它的密码修改为129181367。

在这个方法中,我查询了两次名为张三的用户,第一次查询的结果我把张三的密码进行了set,但是我并没有进行任何的update操作,于是我又查询了一次名为张三的用户,发现第二次查询的结果竟然和我set后的数据一致,但道理应该是不一致的。

二、问题原因

经过我反复研究和测试,先说结论是缓存导致的问题,因为MyBatis的一级缓存是默认开启的,在同一事务中(我加了@Transactional这个注解),相同的查询只会返回缓存中的对象,而不会从数据库中重新加载,换而言之,这2个对象指向的都是同一个对象地址,是同一个实例,而不是新的实例。

三、解决方案

3.1、去除@Transactional这个注解(不推荐)

不过这个办法不推荐,因为在一些特定场景中我们需要保证事务的一致性,虽然去掉了可以解决查询结果不一致的问题,但是牺牲了事务的一致性,如下图所示:

3.2、使用sqlSession.clearCache()方法(推荐)

在执行插入、更新或删除等操作后,使用sqlSession.clearCache() 方法手动清理本地Session缓存,以确保后续查询可以获取到最新的数据。

注入这个jar包下面的SqlSession;

import org.apache.ibatis.session.SqlSession;
@Resource
private SqlSession sqlSession;

调用方法:

sqlSession.clearCache();

这样就可以完美解决了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄团团

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值