前言:
本篇文章主要讲解Mybatis缓存机制的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。
如果文章有什么需要改进的地方欢迎大佬提出,对大佬有帮助希望可以支持下哦~
小威在此先感谢各位小伙伴儿了😁
以下正文开始
Mybatis缓存概述
Mybatis的缓存分为一级缓存和二级缓存。一级缓存是SqlSession级别的,主要用于减少同一个SqlSession中相同的查询语句执行的次数;而二级缓存是mapper级别的,多个SqlSession可以共享一个UserMapper的二级缓存。
一级缓存
首先先详细介绍一下一级缓存。
一级缓存是默认开启的,不需要我们开发者特别配置。当使用SqlSession进行查询时,如果下一次再使用相同的SqlSession进行查询,就会直接从缓存中取数据,如果没有才从数据库中取数据。
那么一级缓存是如何失效的呢?
当执行增删改操作(insert、update、delete)时,会清空一级缓存,因为增删改操作可能会改变数据库中的数据,为了保证数据的一致性,需要清空缓存
。
二级缓存
接着我们学习一下二级缓存。
二级缓存需要我们手动开启和配置。在mapper.xml文件中添加标签,就可以开启二级缓存。对于使用注解的mapper,我们在接口上使用@CacheNamespace注解也可以启用二级缓存。
那么二级缓存共享可以共享吗?
二级缓存是mapper级别的,多个SqlSession是可以共享同一个mapper的二级缓存。这样可以减少跨SqlSession中相同的查询语句执行的次数,进一步提高性能。
缓存实例分析
接下来我们通过一个之前课设的例子来深入理解Mybatis的缓存机制。
首先,我们需要创建一个实体类User,如下:
public class User {private int id;private String name;private String email;// 此处省略了getter和setter方法
}
接着,我们需要创建一个UserMapper接口,如下:
public interface UserMapper {List<User> selectUsers(); // 默认返回全部用户信息
}
然后在对应的MyBatis配置文件中添加一个使用一级缓存的SQL语句:
<select id="selectUsers" resultType="com.example.demo.model.User">SELECT * FROM users WHERE is_delete=0
</select>
然后在Mapper接口中使用该SQL语句,并且在调用方法前面添加一行代码,用来开启一级缓存:
public class UserService {@Cacheable("userList") // 使用一级缓存的示例,执行完毕后自动清除数据到二级缓存中。若不需要将结果存储到二级缓存中,可以在@Cacheable注解中添加key属性为null即可。例如:@Cacheable(key = "userList")public List<User> selectUsers() {return userMapper.selectUsers(); // 默认返回全部用户信息}
}
我们这个例子介绍了如何使用一级缓存。二级缓存的使用相对复杂一些,需要考虑更多的问题和情况。同时也要注意一些细节问题,比如当一个Mapper有多个SqlStatement时,默认只有一个被应用到二级缓存中,如果有多个需要执行相同Sql语句的情况(比如对多个不同的结果集进行合并),需要手动配置多个不同的SqlStatement对应不同的二级缓存名称。
同时我们也要注意数据一致性问题,避免在多个SqlSession之间产生冲突。
注意事项
除了上面所说的之外,还需要注意这些问题:
- 脏读问题:由于缓存的存在,可能会导致脏读问题。即当数据库中的数据已经改变,但缓存中的数据还未更新时,读取到的将是旧的数据。因此,在使用缓存时,需要注意数据的实时性和一致性。
- 缓存策略选择:一级缓存和二级缓存各有优缺点,需要根据我们的实际应用场景和需求进行选择。对于读多写少的应用,可以更多地使用二级缓存;对于读写都比较频繁的应用,可能需要慎用缓存,避免数据的不一致性。
文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。