一、什么是一级缓存
每一次在和数据库进行会话的过程中,MyBatis 都会创建一个SqlSession
对象。同一次会话期间,只要是查询过的数据,都会保存在当前SqlSession
对象的一个Map
中。所以在一次会话的过程中,如果我们对一条查询SQL 语句进行了多次执行,经过判断后和之前执行的查询语句相同,并且在缓存中存在该SQL 语句的执行结果,那么这次查询就不会再从数据库中获取数据,而是直接从缓存中获取数据。
因为一级缓存是建立在SqlSession
对象中的,所以也可以说一级缓存是一个SqlSession
级别的缓存。在默认的情况下,一级缓存是开启的。
下面我们就来体验一下一级缓存的作用。
二、一级缓存初体验
因为一级缓存是默认开启的,所以不需要我们进行任何配置。
mapper 接口:
Employee getEmpById(Integer id);
- 1
SQL 映射文件:
<select id="getEmpById" resultType="com.jas.mybatis.bean.Employee">
SELECT * FROM t_employee WHERE id = #{id}
</select>
- 1
- 2
- 3
测试代码:
// 用于创建SqlSession 对象
private SqlSession getSqlSession() throws IOException {
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
@Test
public void testCache() throws IOException {
SqlSession sqlSession = getSqlSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
// 从数据库中获得id 为1 的员工信息
Employee employee1 = employeeMapper.getEmpById(1);
System.out.println(employee1);
// 再一次从数据库中获得id 为1 的员工信息
Employee employee2 = employeeMapper.getEmpById(1);
System.out.println(employee2);
sqlSession.close();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
上面的测试过程中一共对id
为1 的员工信息进行了两次查询,并且在中间过程中没有进行其他的操作,下面我们通过SQL 日志来看看执行的过程。
虽然我们执行了两次查询,但是从执行结果来看,其实只发送了一条SQL 语句,在第二次获得员工信息的时候并不是从数据库中获取数据,而是直接在一级缓存中获得数据,这就是一级缓存起到的作用。
三、一级缓存失效
我们知道,一级缓存是一个SqlSession
级别的缓存,所以一级缓存在工作的过程中会有一定的局限。
一级缓存失效的情况:
1.只对当前SqlSession
对象生效,对于其他的SqlSession
来说一级缓存是不起作用的。
2.是同一个SqlSession
对象,但是执行的是不同条件的SQL 查询语句。
3.同一个SqlSession
对象执行同一条件的查询语句,但中间执行了增删改的操作,之前一级缓存中的数据会失效。如果执行的是不同条件的查询语句,一级缓存仍然生效,并且会把新的查询数据也加入到一级缓存中。
4.多次相同查询语句在执行期间通过sqlSession.clearCache();
方法清除了缓存。
5.SqlSession
对象调用了close()
方法,当前会话结束,一级缓存不再生效。
对于上面的几种情况,一级缓存都是不起作用的。所以在处理业务的时候要根据需求,具体分析能不能使用一级缓存。
四、总结
这篇博文主要对MyBatis 中的一级缓存进行了一些介绍,并把常见的一级缓存失效的几种情况也进行了描述,希望能够为学习缓存的小伙伴提供一些帮助。如果想要更深了解一些关于一级缓存原理的知识,可以点击下面的链接,总结的很清楚,前排致敬前辈。