mybatis缓存
MyBatis 内置了一个强大的事务性查询缓存机制,当你查询了一次数据时,他会保存到缓存中,当你第二次查询这个数据时,它不会去数据库查找,而是直接从缓存中去取!
一级缓存
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。可以理解为sqlsession级别的!
@Test
public void queryUserById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);//第一次查询1号用户
System.out.println("第一次查询1号用户user为"+user);
System.out.println("---------------------------------------------------------------------");
User user2 = mapper.queryUserById(1);//第二次查询1号用户
System.out.println("第二次查询1号用户user2为"+user2);
System.out.println("---------------------------------------------------------------------");
System.out.println("user==user2为"+(user==user2));//数据库只查询了一次
sqlSession.close();
}
数据库只查询了一次
二级缓存(xml级别)
要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
<cache/>
基本上就是这样。这个简单语句的效果如下:
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
- 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
<!--开启二级缓存,作用于整个namespace(整个xml)的-->
<cache eviction="FIFO"
flushInterval="6000"
size="512"
readOnly="true"/>
<!--只要开启了二级缓存,在同一个Mapper下就有效
所有的数据都会放到一级缓存中
只有当会话提交或者关闭的时候,才会提交到二级缓存中-->
缓存失效原因
@Test
public void cache(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);//第一次查询1号用户
System.out.println("第一次查询1号用户user为"+user);
//mapper.updateUser(new User(2, "aaa", "a123bbb"));//修改操作
sqlSession.clearCache();//手动清理缓存
System.out.println("---------------------------------------------------------------------");
User user2 = mapper.queryUserById(1);//第二次查询1号用户
System.out.println("第二次查询1号用户user2为"+user2);
System.out.println("---------------------------------------------------------------------");
System.out.println("user==user2为"+(user==user2));//false 数据库查询了2次
/*缓存失效的原因:
1.查询不同的东西
2.增删改查操作可能会改变原有的数量,所有必定刷新缓存
3.查询不同的Mapper.xml
4.手动清理缓存
*/
sqlSession.close();
//一级缓存是默认开启,只在sqlSession中有效。
}
数据库查询了两次
开启二级缓存效果
public void cache2(){
//开启二级缓存
SqlSession sqlSession = MybatisUtils.getSqlSession();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);//sqlSession第一次查询1号用户
System.out.println("第一次查询1号用户user为"+user);
System.out.println("---------------------------------------------------------------------");
sqlSession.close();//关闭后,一级缓存里面就没有了,提交到二级缓存
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);//sqlSession2查询1号用户,从二级缓存里获取
System.out.println("第二次查询1号用户user2为"+user2);
System.out.println("---------------------------------------------------------------------");
sqlSession2.close();
//顺序:用户先从二级缓存取,在到一级缓存,都没有就去查询数据库
}
数据库只查询了一次
原理
用户查询数据时先通过二级缓存,然后在到一级缓存,最后都没有就去数据库查询。
作者有话说
博客创作不易,希望看到这里的读者动动你的小手点个赞,如果喜欢的小伙伴可以一键三连,作者大大在这里给大家谢谢了。