08 MyBatis 一级缓存 & 二级缓存

本文详细解析MyBatis的一级缓存和二级缓存工作原理,包括缓存配置、使用步骤及缓存失效机制。一级缓存作用于单次SqlSession,而二级缓存基于namespace级别,适用于全局范围,通过合理配置可显著提升数据库查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一级缓存(SqlSession)

一级缓存也称为本地缓存。与数据库同一次回话期间查询到的数据会放在本地缓存中。以后查询同样的数据就会从本地缓存中获取,而不是从数据库获取。

示例


UserinfoMapper mapper = session.getMapper(UserinfoMapper.class);
//第一次查询 101 数据
Userinfo userinfo = mapper.selectOne(101);
System.out.println(JSON.toJsonString(userinfo));

//第二次查询同样的数据(从缓存中获取,缓存中没有在查询数据库)
Userinfo userinfo2 = mapper.selectOne(101);
System.out.println(JSON.toJsonString(userinfo2));
//二级缓存返回的是同一个对象引用
System.out.println(userinfo == userinfo2);

一级缓存又称为SqlSession 缓存,无法关闭,只要在通过一个SqlSession对象中都可以使用对应的一级缓存。

一级缓存失效方式:

① 重新获取SqlSession,SqlSession不同所以缓存无法使用。

② 第二次查询的不是同一个数据。

③ 两次查询之间有其他CRUD操作。

④ 手动清除一级缓存。

二级缓存(namespaces)

二级缓存也称为全局缓存。二级缓存是基于namespaces级别的缓存,一个namespaces 对应一个二级缓存。

二级缓存工作机制

  1. 一个会话查询的数据会自动保存在一级缓存中。
  2. 如果会话关闭,一级缓存中的数据会被保存到二级缓存中。新的会话会优先去二级缓存中查找数据。
  3. 不同的namespaces查询的数据会放在自己对应的缓存中(Map中)

二级缓存使用步骤

1. 总配置文件开启全局二级缓存配置(default true)
<settings>
    <setting name="cacheEnabled" value="true" />
</settings>
2. Mapper文件指定使用缓存
<cache readOnly="true" size="500" flushInterval="120000" eviction="LRU" />

eviction : 缓存回收策略
    LRU: 最近最少使用,移除最长时间不被使用的对象,默认策略

    FIFO: 先进先出,按对象进入缓存的顺序来移除他们

    SOFT: 软引用,移除基于垃圾回收器状态和软引用规则的对象

    WEAK: 弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象

flushInterval : 缓存刷新间隔时间(毫秒时间),默认不清空
readOnly : 缓存是否只读;
     true : MyBatis 认为所有从缓存中获取数据的操作都是只读。不会修改数据。MyBatis 为了加快获取速度,直接就会将数据在缓存中的引用交给用户。
     false : 非只读。MyBatis 会识别到数据可能会被修改,用户获得的数据是MyBatis 利用序列化和反序列化克隆的新数据交给用户(建议实体类实现序列化接口)。
size : 缓存存放多少数据。

3. 具体SQL语句处使用缓存(default true)
<!--  useCache="true" 默认开启  -->
<select id="findAll" resultType="java.util.Map" useCache="true">
    SELECT * from table
</select>

示例

SqlSession session1 = sf.openSession();
SqlSession session2 = sf.openSession();

UserinfoMappe mapper1 = session1.getMapper(UserinfoMapper.class);
UserinfoMappe mapper2 = session2.getMapper(UserinfoMapper.class);

Userinfo userinfo1 = mapper1.selectOne(101);
//会话关闭时,缓存会保存到二级缓存中
session1.close();

//从二级缓存中获取数据,不会从新发送新的 SQL 语句
Userinfo userinfo2 = mapper2.selectOne(101);
session2.close();

使用二级缓存需要注意,缓存有优先存放在一级缓存中,只有当一级缓存对应的SqlSession关闭的时候才会将数据保存到二级缓存中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值