MyBatis一级缓存与二级缓存详解及代码演示:
摘要:
- MyBatis是一个优秀的Java持久层框架,为了提高数据访问效率,它提供了一级和二级缓存机制。
- 本文将深入讲解MyBatis的一级缓存和二级缓存的工作原理,并通过代码示例进行演示,帮助读者更好地理解和应用这两种缓存。
一、MyBatis一级缓存:
1.1 工作原理
- MyBatis的一级缓存是基于SqlSession的。在同一个SqlSession中,相同的SQL查询会被缓存,以避免重复查询数据库。
- 当SqlSession执行查询时,MyBatis会首先检查一级缓存中是否有相应的结果,如果有则直接返回,否则查询数据库并将结果存入一级缓存。
1.2 代码演示
下面展示一些 UserMapper.java
。
package com.itxiaozhou.mapper;
import com.itxiaozhou.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
// 根据Java的命名习惯,方法名应该是小驼峰式,并且具有描述性
User findUserById(Long id);
}
下面展示一些 UserMapper.xml
。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itxiaozhou.mapper.UserMapper">
<select id="findUserById" resultType="com.itxiaozhou.entity.User">
SELECT id, username, phone, status FROM tb_user WHERE id = #{id}
</select>
</mapper>
下面展示一些 测试代码
。
@SpringBootTest
public class UserTest {
@Autowired
private SqlSessionFactory sqlSessionFactory;
@Test
void test1() {
// 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取UserMapper接口的代理对象
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
// 执行sql
User user1 = userMapper1.findUserById(2L);
System.out.println(user1);
System.out.println("\n------------------------------------\n");
User user2 = userMapper1.findUserById(2L);
System.out.println(user2);
// 关闭资源
sqlSession.close();
}
1.3 注意事项:
- 一级缓存的生命周期与SqlSession相同,当SqlSession关闭或执行了更新操作(如insert、update、delete)时,一级缓存会被清空。
- 一级缓存是默认开启的,不需要额外配置。
二、MyBatis二级缓存:
2.1 工作原理:
- MyBatis的二级缓存是基于命名空间的,它可以跨多个SqlSession共享数据。
- 不同的SqlSession之间,相同的SQL查询可以通过二级缓存共享结果。
- 二级缓存可以显著减少数据库查询次数,提高性能。
2.2 配置二级缓存
要使用二级缓存,需要在Mapper的配置文件中启用它:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itxiaozhou.mapper.UserMapper">
<cache/>
<select id="findUserById" resultType="com.itxiaozhou.entity.User">
SELECT id, username, phone, status FROM tb_user WHERE id = #{id}
</select>
</mapper>
此外,还可以在标签中添加属性来自定义二级缓存的行为,例如设置缓存的过期时间、大小等。
2.3 代码演示
下面是一个使用 MyBatis 二级缓存的代码示例:
@Test
void test2() {
// 获取SqlSession对象,用它来执行sql
SqlSession sqlSession1 = sqlSessionFactory.openSession();
// 执行sql
// 获取UserMapper接口的代理对象
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.findUserById(2L);
System.out.println(user1);
// 关闭资源
sqlSession1.close();
System.out.println("\n------------------------------------\n");
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = userMapper2.findUserById(2L);
System.out.println(user2);
// 关闭资源
sqlSession2.close();
}
2.4 注意事项
- 二级缓存的生命周期与应用程序相同,当应用程序关闭时,二级缓存会被清空。
- 二级缓存可以在多个SqlSession之间共享数据,但需要注意数据一致性问题。
- 不同的命名空间(Mapper)有各自独立的二级缓存,但可以通过配置实现缓存共享。
三、总结:
MyBatis的一级缓存和二级缓存为提高数据访问性能提供了有效手段。一级缓存适用于单个SqlSession内的重复查询,而二级缓存适用于跨多个SqlSession的重复查询。在使用缓存时,需要注意缓存的生命周期、作用范围以及可能的数据一致性问题。通过合理配置和使用缓存,可以显著提高MyBatis应用的性能。