Mybatis的缓存机制

本文最后更新于:3 天前

Mybatis的缓存机制

缓存

将一些不太常变更的数据,保存在内存中,或者某些高速存储器上,从而提升我们查询数据的效率

Mybatis的两级缓存

1、一级缓存与SqlSessoin会话绑定,默认开启

2、二级缓存是应用程序全局缓存,所有SqlSession共享,需要手动开启

  • 一级缓存是将数据保存在内存中(一个巨大的HashMap),一个SqlSession对应一个HashMap

  • 一级缓存的生命周期:随着SqlSession创建而创建,当SqlSessioin Close关闭时跟着销毁,一级缓存的生命周期较短

  • 二级缓存是应用程序全局的缓存,只要Mybatis在启动的过程中,二级缓存就会一直存在,二级缓存的载体可以是内存中的一个HashMap,也可以是一个单体的缓存框架,例如Ehcache、分布式NoSql数据库Redis。对于二级缓存来说,所有的SqlSesion都可以访问其中的数据。

  • 二级缓存的生命周期:随着MybatisSessionFactory的创建而创建,在SessionFactory销毁时消失

  • 二级缓存相较于一级缓存,二级缓存存活周期更长,需要的空间更大,但缓存的命中率更高

一级缓存默认开启

1
2
3
4
5
6
SqlSession session = sessionFactory.openSession();
Employee emp1 = session.selectOne(statement, 7566);
System.out.println(emp1);
Employee emp2 = session.selectOne(statement, 7566);
System.out.println(emp2);
session.close();
1
2
..entity.Employee@589838eb
..entity.Employee@589838eb
1
2
3
4
5
6
7
8
SqlSession session1 = sessionFactory.openSession();
Employee emp1 = session1.selectOne(statement, 7566);
System.out.println(emp1);
session1.close();
SqlSession session2 = sessionFactory.openSession();
Employee emp2 = session2.selectOne(statement, 7566);
System.out.println(emp2);
session2.close();
1
2
..entity.Employee@4dfa3a9d
..entity.Employee@464bee09

开启二级缓存

  • 映射器 emp.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<mapper namespace="..mapper.EmpMapper">
<!-- cache size="512":在二级缓存中最多容纳512个对象 -->
<!-- eviction="FIFO":缓存清除策略FIFO、LRU -->
<!-- flushInterval="60000":定时(每60s)兑缓存进行清理 -->
<!-- readOnly="true":保存在缓存中的对象不允许被修改 -->
<cache size="512" eviction="FIFO" flushInterval="60000" readOnly="true"/>

<!-- useCache="false":不使用缓存 -->
<!-- 通常查询结果为多个对象时,不建议使用二级缓存。因为list列表中任何一个元素发生变化后,Mybatis为了保证缓存中的数据和数据库中数据的一致,会将整个list进行处理 -->
<select id="findAll"
resultType="..entity.Employee" useCache="false">
select * from emp
</select>

<select id="findById" parameterType="int"
resultType="..entity.Employee" useCache="true">
select * from emp where empno = #{value}
</select>
</mapper>
  • 使用二级缓存存储的对象对应实体类需要实现Serializable接口
1
2
3
4
5
6
7
8
SqlSession session1 = sessionFactory.openSession();
Employee emp1 = session1.selectOne(statement, 7566);
System.out.println(emp1);
session1.close();
SqlSession session2 = sessionFactory.openSession();
Employee emp2 = session2.selectOne(statement, 7566);
System.out.println(emp2);
session2.close();
1
2
..entity.Employee@589838eb
..entity.Employee@589838eb

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!