MyBatis:缓存

简介

什么是缓存?

  • 存在内存中的数据
  • 将用户经常查询的数据存放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
    为什么使用缓存?
  • 减少和数据库的交互次数,减少系统开销,提高系统效率
    什么样的数据能使用缓存?
  • 经常查询并且不经常改变的数据

    MyBatis缓存

  • MyBatis包含一个非常浅的嘎的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大地提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存
    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来定义二级缓存。

一级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间(从SqlSession创建到关闭)查询到的数据会放在本地缓存中
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库

测试

  1. 启动日志
  2. 根据Id搜索用户
  3. 搜索同一个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
15
Opening 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.

结果分析

  1. 只执行了一次Sql语句
  2. 两个对象是相等的

    缓存失效

  3. 查询不同的东西
  4. 增删改操作,可能会改变数据库的内容,肯定会刷新缓存
  5. 查询不同的Mapper.xml
  6. 手动清理缓存(sqlSession.clearCache();)

一级缓存的实现就是一个Map,可以通过打断点来证明。

缓存顺序

  1. 先看二级缓存中有没有
  2. 再看一级缓存中有没有
  3. 查询数据库