Mybatis缓存机制详解与实例分析

Mybatis缓存概述

Mybatis的缓存分为一级缓存和二级缓存。一级缓存是SqlSession级别的,主要用于减少同一个SqlSession中相同的查询语句执行的次数 ;而二级缓存是mapper级别的,多个SqlSession可以共享一个UserMapper的二级缓存。

一级缓存

首先先详细介绍一下一级缓存。

一级缓存是默认开启的,不需要我们开发者特别配置。当使用SqlSession进行查询时,如果下一次再使用相同的SqlSession进行查询,就会直接从缓存中取数据,如果没有才从数据库中取数据。

那么一级缓存是如何失效的呢?

当执行增删改操作(insert、update、delete)时,会清空一级缓存,因为增删改操作可能会改变数据库中的数据,为了保证数据的一致性,需要清空缓存。

二级缓存

接着我们学习一下二级缓存。

二级缓存需要我们手动开启和配置。在mapper.xml文件中添加标签,就可以开启二级缓存。对于使用注解的mapper,我们在接口上使用@CacheNamespace注解也可以启用二级缓存。

那么二级缓存共享可以共享吗?

二级缓存是mapper级别的,多个SqlSession是可以共享同一个mapper的二级缓存。这样可以减少跨SqlSession中相同的查询语句执行的次数,进一步提高性能。

缓存实例分析

接下来我们通过一个之前课设的例子来深入理解Mybatis的缓存机制。

首先,我们需要创建一个实体类User,如下:

java 复制代码
public class User {
    private int id;
    private String name;
    private String email;
    // 此处省略了getter和setter方法
}

接着,我们需要创建一个UserMapper接口,如下:

java 复制代码
public interface UserMapper {
    List<User> selectUsers(); // 默认返回全部用户信息
}

然后在对应的MyBatis配置文件中添加一个使用一级缓存的SQL语句:

xml 复制代码
<select id="selectUsers" resultType="com.example.demo.model.User">
    SELECT * FROM users WHERE is_delete=0
</select>

然后在Mapper接口中使用该SQL语句,并且在调用方法前面添加一行代码,用来开启一级缓存:

java 复制代码
public class UserService {
    @Cacheable("userList") // 使用一级缓存的示例,执行完毕后自动清除数据到二级缓存中。若不需要将结果存储到二级缓存中,可以在@Cacheable注解中添加key属性为null即可。例如:@Cacheable(key = "userList")
    public List<User> selectUsers() {
        return userMapper.selectUsers(); // 默认返回全部用户信息
    }
}

我们这个例子介绍了如何使用一级缓存。二级缓存的使用相对复杂一些,需要考虑更多的问题和情况。同时也要注意一些细节问题,比如当一个Mapper有多个SqlStatement时,默认只有一个被应用到二级缓存中,如果有多个需要执行相同Sql语句的情况(比如对多个不同的结果集进行合并),需要手动配置多个不同的SqlStatement对应不同的二级缓存名称。

同时我们也要注意数据一致性问题,避免在多个SqlSession之间产生冲突。

注意事项

除了上面所说的之外,还需要注意这些问题:

  • 脏读问题:由于缓存的存在,可能会导致脏读问题 。即当数据库中的数据已经改变,但缓存中的数据还未更新时,读取到的将是旧的数据。因此,在使用缓存时,需要注意数据的实时性和一致性。
  • 缓存策略选择:一级缓存和二级缓存各有优缺点,需要根据我们的实际应用场景和需求进行选择。对于读多写少的应用,可以更多地使用二级缓存;对于读写都比较频繁的应用,可能需要慎用缓存,避免数据的不一致性。
相关推荐
明月_清风1 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
hsfxuebao4 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
打工仔折腾 AI4 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
架构技术专栏4 小时前
交叉熵:AI 怎样给概率预测打分
后端
IT_陈寒6 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
要努力啊4697 小时前
用 Codex 加速 Java 开发:从代码生成到测试覆盖的完整实战
后端
dora7 小时前
LangChain4j 新手入门实战教程(Java版)
后端·langchain·agent
蜗牛互联网7 小时前
MongoDB Atlas Agent Engine之后,如何用版本门禁防止陈旧写入
java·数据库·人工智能·后端·mongodb
付威20237 小时前
Rust 生命周期:为什么要有它,实际代码里到底怎么用?
后端
海岳云舟7 小时前
spring使用kafka的三种方式(listener、container、stream)
后端