1.了解一级缓存
MyBatis 一级缓存是指在同一个 SqlSession 中,对于相同的查询语句和参数,MyBatis会将查询的结果缓存起来,下次再执行相同的查询时,直接从缓存中获取结果,避免了重复查询数据库的开销。
一级缓存是默认开启的,可以通过配置来关闭或手动清除。一级缓存的作用范围是在一个SqlSession 内部有效,不同的SqlSession 之间的缓存互相独立。
一级缓存的工作原理如下:
-
当执行一个查询语句时,MyBatis会先检查缓存中是否已经有该查询的结果,如果有,则直接返回缓存中的结果。
-
如果缓存中没有该查询的结果,则继续执行查询操作,并将查询结果放入缓存中。
-
下次执行相同的查询时,MyBatis会先检查缓存中是否已经有该查询的结果,如果有,则直接返回缓存中的结果。
可以通过配置文件中的<setting>
元素来控制一级缓存的开启和关闭,例如:
<setting name="localCacheScope" value="STATEMENT"/>
将localCacheScope
设置为STATEMENT
表示关闭一级缓存,设置为SESSION
表示开启一级缓存。另外,在需要手动清除一级缓存时,可以调用SqlSession的clearCache()
方法来清空缓存。
2.MyBatis 一级缓存的简单示例
首先,假设我们有一个 StudentMapper 接口来操作用户信息,其中包含了查询用户列表的方法 getStudentClssAll()
。
然后,在配置文件中设置开启一级缓存
接着,创建 StudentMapper.xml
文件,配置查询语句和映射规则
大家可以写单表的简单查询
在测试类代码中,我们可以通过 SqlSessionFactory
获取一个 SqlSession
实例,并调用 StudentMapper的方法进行查询
运行结果
在上述示例中,第一次调用 studentList1()
方法时,会从数据库中查询用户列表,并将结果放入一级缓存。然后,第二次调用 studentList2()
方法时,会直接从一级缓存中获取结果,而不再访问数据库。
2.了解二级缓存的配置
二级缓存是MyBatis中的一种缓存机制,用于缓存查询结果。它位于SqlSessionFactory的作用域内,可以在多个会话之间共享。
当使用二级缓存时,首先需要在配置文件中进行相应的设置。在 <settings>
标签下,添加 <setting name="cacheEnabled" value="true"/>
,这样即可启用二级缓存。
MyBatis的二级缓存可以提高查询性能,减少数据库访问次数,但需要注意处理对象修改和缓存命中率等问题。
<setting name="cacheEnabled" value="true"/>
MyBaits二级缓存的示例
1.首先,在MyBatis配置文件中启用二级缓存。在 <configuration>
标签下添加如下配置
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.在Mapper接口对应的映射文件中开启二级缓存。在需要缓存结果的查询语句上添加 cache="true"
属性。
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" resultType="User" cache="true">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
3.在Java代码中使用Mapper接口调用查询方法,并观察缓存效果。
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = ... ;
// 打开一个会话
try (SqlSession sqlSession1 = sqlSessionFactory.openSession()) {
// 获取Mapper接口实例
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
// 第一次查询,会从数据库中获取数据并放入缓存
User user1 = userMapper1.getUserById(1);
// 第二次查询,直接从缓存中获取数据
User user2 = userMapper1.getUserById(1);
// 修改用户信息
user2.setName("New Name");
userMapper1.updateUser(user2);
// 提交事务
sqlSession1.commit();
}
// 再次打开一个会话
try (SqlSession sqlSession2 = sqlSessionFactory.openSession()) {
// 获取Mapper接口实例
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
// 第三次查询,由于修改了用户信息,缓存失效,会重新查询数据库
User user3 = userMapper2.getUserById(1);
}