Mybatis 禁用一级缓存

**

遇到问题的场景:

**
一张数据库中的表:table_name,这张表在开发的过程中对应两个Mapper(比如两个模块:模块a, 模块b),mybatis 默认是开启一级缓存的。现在的情况是我在模块a中用程序修改了table_name中的某个字段值(比如:field原来是0,现在改为1),通过模块a现在已经修改完了。我在模块b中查询时发现表table_name中的field字段还是0。由于之前查询过,参数没有发生任何变化,导致模块b中走了mybatis缓存。
原来的sql:

<select id="selectById" resultMap="BaseResultMap" >
        select
        <include refid="Base_Column_List"/>
        from table_name
        WHERE id = #{id,jdbcType=VARCHAR}
    </select>

解决方式:
1. 这种方式是我实际采用的方式

<!--在sql语句中增加了 flushCache=true-->
<select id="selectById" resultMap="BaseResultMap"  flushCache="true">
        select
        <include refid="Base_Column_List"/>
        from table_name
        WHERE id = #{id,jdbcType=VARCHAR}
    </select>

2. 这种方式也是可以解决的

<!--生成随机值,保证每次参数都不一样-->
<select id="selectById" resultMap="BaseResultMap"  flushCache="true">
        select
        <include refid="Base_Column_List"/>
        from table_name
        WHERE id = #{id,jdbcType=VARCHAR}
        AND #{random,jdbcType=VARCHAR} = #{random,jdbcType=VARCHAR}
    </select>
### MyBatis 一级缓存会话的概念及工作原理 MyBatis一级缓存也被称为 **Session 缓存** 或者 **本地缓存**,它是默认开启的,并且作用范围仅限于单个 SqlSession 生命周期内。这意味着,在同一个 SqlSession 中执行的多次查询操作如果满足一定条件,则可以命中缓存而无需再次访问数据库。 #### 工作原理 当通过 `SqlSession` 执行一次查询时,MyBatis 将查询结果存储到该 Session 的内部缓存中[^1]。随后在同一 SqlSession 范围内的相同 SQL 查询请求可以直接从缓存获取数据,而不是重新向数据库发起查询。这种行为显著减少了重复查询带来的性能开销。 然而需要注意的是,一旦调用了 `commit()` 方法或者关闭了当前的 `SqlSession` 实例之后,这个缓存就会被清空。因此每次新创建一个 `SqlSession` 都意味着一个新的独立的一级缓存区域。 另外值得注意的地方在于更新、删除或插入等修改型的操作都会导致清除掉对应表的相关记录条目在内存中的副本信息以防脏读现象发生。 以下是关于如何使用以及一些注意事项: - 如果希望禁用一级缓存可以在配置文件设置 `<setting name="localCacheScope" value="STATEMENT"/>`, 默认情况下它设为 SESSION 表明整个 session 使用统一缓存。 下面给出一段简单的代码展示了一次典型的 mybatis 操作流程包括启用和管理其内置缓存机制的例子: ```java // 获取sqlSessionFactory实例并打开session try (SqlSession sqlSession = sqlSessionFactory.openSession()) { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 第一次查询触发实际SQL执行并将结果放入缓存 List<User> usersFirstQuery = mapper.selectUsers(); // 第二次同样条件下查询直接返回缓存内容而不发往DB List<User> usersSecondQuery = mapper.selectUsers(); } catch(Exception e){ System.out.println(e.getMessage()); } ``` 上述例子展示了在一个未提交事务期间两次相同的 select 请求是如何只产生一条物理查询命令从而提高效率的同时保持一致性。 #### 设计考量因素 对于大规模并发环境下的应用来说,合理规划好各级别的缓存策略至关重要。虽然一级缓存简单易用但对于长时间存活的对象可能不是最佳选择因为缺乏全局视角可能导致某些场景下频繁刷新造成额外负担;此时引入二级缓存或者其他形式分布式解决方案就显得尤为重要。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值