缓存

2.一级缓存

1
2
3
4
5
6
7
8
9
10
11
12
SqlSession sqlSession = MybatisUnit.getSqlSession ();
BlogMapper mapper = sqlSession.getMapper (BlogMapper.class);
Map<String, Object> map = new HashMap<> ();
map.put ("author","queen");
Blog blog = mapper.getBlog (map);
System.out.println (blog);
System.out.println ("****************************");
map.put ("author","queen");
Blog blog1 = mapper.getBlog (map);
System.out.println (blog1);
sqlSession.commit ();
sqlSession.close ();

一级缓存是在sqlsession层面上的,在sqlsession产生到关闭之间的涉及增删改查的数据都会被保存下来

效果:

1
2
3
4
5
6
7
8
==>  Preparing: select * from mybatis.blog where author=?
==> Parameters: queen(String)
<== Columns: id, title, author, create_time, views
<== Row: 566993470e944aa2ba4003c7ccbfaf5d, 我是最帅的, queen, 2020-08-09 10:23:10, 10
<== Total: 1
Blog{author='queen', createTime=null, id='566993470e944aa2ba4003c7ccbfaf5d', title='我是最帅的', views=10}
****************************
Blog{author='queen', createTime=null, id='566993470e944aa2ba4003c7ccbfaf5d', title='我是最帅的', views=10}

由于存在缓存,我们的第二次查询就没有执行查询语句,而是直接从缓存中取出来;

可以利用sqlSession.clearCache()来清除缓存;清除以后的话,就会在加载一次数据库;

缓存消失的原因:

  • 自己清除,利用函数
  • 查询语句会被我们的增删改语句覆盖,目的就是我们的增删改已经修改了数据,再次访问缓存里面的就会导致取出的数据不真实;
  • 查询的是不同的mapper.xml下面的东西
  • 查询不同的东西,比如查询一号和二号

3.二级缓存

当你使用二级缓存的时候,只有一级缓存会话消失后才会缓存到二级缓存;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@org.junit.Test
public void test2 () {
SqlSession sqlSession = MybatisUnit.getSqlSession ();
SqlSession sqlSession2 = MybatisUnit.getSqlSession ();
BlogMapper mapper = sqlSession.getMapper (BlogMapper.class);
Map<String, Object> map = new HashMap<> ();
map.put ("author","Queen and King");
Blog blog = mapper.getBlog (map);
System.out.println (blog);
sqlSession.close ();//会话关闭,一级缓存变成二级缓存

System.out.println ("++++++++++++++++++++++++++++++++++++++++++++++++");

BlogMapper mapper2 = sqlSession2.getMapper (BlogMapper.class);
Map<String, Object> map2 = new HashMap<> ();
map2.put ("author","Queen and King");
Blog blog2 = mapper2.getBlog (map);
System.out.println (blog2);
sqlSession2.close ();
}

使用cache就只需要一个标签就可以了

注意:

  • 缓存的时候,实体类要序列化,所以我们的实体类要继承序列化接口
  • 二级缓存的作用域就是namespace,一个mpper.xml,所有数据都放在先放在一级缓存,只有当我们关闭会话,这个才回到二级缓存;