简介
什么是缓存?
- 存在内存中的数据
- 将用户经常查询的数据存放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
为什么使用缓存? - 减少和数据库的交互次数,减少系统开销,提高系统效率
什么样的数据能使用缓存? - 经常查询并且不经常改变的数据
MyBatis缓存
- MyBatis包含一个非常浅的嘎的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大地提升查询效率。
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来定义二级缓存。
一级缓存
一级缓存也叫本地缓存:
- 与数据库同一次会话期间(从SqlSession创建到关闭)查询到的数据会放在本地缓存中
- 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
测试
- 启动日志
- 根据Id搜索用户
- 搜索同一个Id两次
1
2
3
4
5
6
7
8
9
10
11
12
13
14@Test
public void addInitBlog(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryById(1);
System.out.println(user1);
System.out.println("==========");
User user2 = mapper.queryById(1);
System.out.println(user2);
System.out.println(user1==user2);
sqlSession.close();
}
日志输出:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15Opening JDBC Connection
Created connection 2088371948.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7c7a06ec]
==> Preparing: select * from user where id=?
==> Parameters: 1(Integer)
<== Columns: id, name, pwd
<== Row: 1, xiaoke, 666
<== Total: 1
User{id=1, name='xiaoke', pwd='666'}
==========
User{id=1, name='xiaoke', pwd='666'}
true
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7c7a06ec]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7c7a06ec]
Returned connection 2088371948 to pool.
结果分析
- 只执行了一次Sql语句
- 两个对象是相等的
缓存失效
- 查询不同的东西
- 增删改操作,可能会改变数据库的内容,肯定会刷新缓存
- 查询不同的Mapper.xml
- 手动清理缓存(sqlSession.clearCache();)
一级缓存的实现就是一个Map,可以通过打断点来证明。
缓存顺序
- 先看二级缓存中有没有
- 再看一级缓存中有没有
- 查询数据库