查询结果放到内存中,再次查询,直接从内存中读取返回;
好处:
- 读取速度快
- 减少数据库的压力
一级缓存
指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中
实现
HashMap<K,V>——(sql语句,查询结果)
工作流程
-
对于某个查询,根据statementld,params,rowBounds来构建一个key值,
-
判断从Cache中根据key值获取的数据是否为空
-
若命中,返回结果
-
若未命中:
4.1去数据库里查询
4.2将key和查询结果分别作为key,value存储到Cache中
4.3返回查询结果
CacheKey
由statemId + rowBounds + 传递给JDBC的SQL + SQL的参数值决定
二级缓存
指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出得结果的对象与
第一次存入的对象是不一样的
特点:
- 默认不开启。需要额外配置才能使用
- 存放的是序列化后的数据,而不是对象(所以从缓存中提取的对象,并不是原对象)
- 实体类必须实现
Serializable
接口
使用
- 总的配置文件要开启二级缓存
-
mapper.xml要开启
-
实体类要实现序列化接口
- 需将上一个sqlSession关闭
String resource = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
System.out.println(personMapper.queryById("1"));
sqlSession.close();
PersonMapper personMapper2 = sqlSession2.getMapper(PersonMapper.class);
System.out.println(personMapper2.queryById("1"));
sqlSession2.close()
建议
由于二级缓存是以namespace为单位的,针对一个表的某些操作不在他独立的namespace下进行。(脏数据)
放弃二级缓存,在业务层使用可控制的缓存代替更好。