目录
一.缓存的概念
缓存是存放数据的地方,即将产生的数据暂时存放到内存中。(缓存就是数据交换的缓冲区(称作Cache),是存贮数据(使用频繁的数据)的临时地方。当用户查询数据,首先在缓存中寻找,如果找到了则直接执行。如果找不到,则去数据库中查找。-大佬的解释)
二.一级缓存
-
应用场景(一级&含义)
即通过同一个SqlSession查询出来的数据会被缓存,第二次查询相同的数据的时候会直接从缓存中取数据,不会再去访问数据库再获取数据。
-
开启条件(一级)
Mybatis的一级缓存是默认开启的。
-
失效条件(一级)
- 使用不同的SqlSession
- 两次查询间存在对数据的增删改操作
- 两次查询的查询条件不一致
- 手动清空了缓存
-
一级缓存失效代码示例(后续二级缓存所使用的数据表一致)
下面以查询员工信息为例,即通过员工的id信息查询员工所有的信息(我们通过log4j实现日志功能,来查看查询语句执行的次数,即为访问数据库的次数,需要引入log4j的依赖和文件,可以直接查到)
员工表如下:
mapper.xml如下:
我们先看看SqlSession未失效时,Sql语句的执行情况(使用同一个SqlSession获取Mapper代理对象执行方法,查询员工信息)
/**
* 测试一级缓存未失效的情况
*/
@Test
public void CacheTestAtFirst(){
//获取SqlSession对象(这是封装好了的方法,直接获取)
SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
//获取Mapper代理对象
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
CacheMapper mapper2 = sqlSession1.getMapper(CacheMapper.class);
//第一次查询员工信息
List<EmpMapper> empById1 = mapper1.getEmpById(1);
System.out.println(empById1);
//第二次查询员工信息
List<EmpMapper> empById2 = mapper2.getEmpById(1);
System.out.println(empById2);
//关闭资源
sqlSession1.close();
}
运行结果如下:
结论:我们通过日志可以看到,我们调用了两次查询员工信息的方法,但日志显示只执行了一次Sql语句,即只访问了一次数据库,因为第二次直接从缓存里拿数据了,这就是Mybatis的一级缓存,下面我们再看看一级缓存失效的情况。
以下为“使用不同的SqlSession”.eg(测试类)
测试代码如下:
/**
* 测试一级缓存,Sqlsession级别-使用不同的SqlSession会导致缓存失效
*/
@Test
public void CacheTestByOne(){
//获取两个SqlSession对象
SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
//执行Sql
List<EmpMapper> empById = mapper1.getEmpById(1);
System.out.println(empById);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
//执行Sql
List<EmpMapper> empById1 = mapper2.getEmpById(1);
System.out.println(empById1);
//关闭资源
sqlSession2.close();
sqlSession1.close();
}
运行结果如下:
结论:可以看到,使用不同的SqlSession对象后,日志显示了两次Sql查询语句,即访问了两次数据库,Mybatis的一级缓存失效了。
以下为“手动清空了缓存”.eg
测试代码示例如下:
/**
* 手动清空缓存使得一级缓存失效
*/
@Test
public void CacheTestByOneA(){
SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
List<EmpMapper> empById = mapper1.getEmpById(1);
System.out.println(empById);
//清空缓存
sqlSession1.clearCache();
CacheMapper mapper2 = sqlSession1.getMapper(CacheMapper.class);
List<EmpMapper> empById1 = mapper2.getEmpById(1);
System.out.println(empById1);
sqlSession1.close();
}
运行结果如下:
结论:与第一种失效的情况一致,还有两种条件也会造成Mybatis的一级缓存失效,测试过程类似, 不再一一展示。
三.二级缓存
-
应用场景(二级&含义)
和一级缓存的定义相似,即由同一个SqlSessionFactory创建的(不同)SqlSession对象查询的结果会被缓存。
-
开启条件(二级)
1.在mapper.xml文件中设置<settings>标签,默认是开启的,不需要设置
<settings> <setting name=”cacheEnabled” value=”true”/> settings>
2.在mapper.xml文件设置<cache/>标签
3.查询数据所转换的实体类类型必须转换实现序列化接口
4.必须在SqlSession关闭或提交后,才会开启二级缓存
二级缓存开启成功示例:
测试代码如下:
@Test
public void CacheTestByTwo() throws IOException {
//1.获取核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取Builder,从同一个sqlSessionFactory中获取SqlSession对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
List<EmpMapper> emp1 = mapper1.getEmpById(1);
System.out.println(emp1);
//关闭SqlSession
sqlSession1.close();
List<EmpMapper> emp2 = mapper2.getEmpById(1);
System.out.println(emp2);
sqlSession2.close();
sqlSession1.close();
}
运行结果如下:
结论:可以看到日志中只执行了一次Sql语句,即两次查询中,只访问了一次数据库(注意Mybatis的缓存查询顺序,先二级再一级,其中显示的命中率Hit Ratio也意味开启了二级缓存)
-
失效条件(二级)
- 两次查询之间执行了一次增删改操作
- SqlSession未关闭,数据被保存在一级缓存中
整合第三方缓存EHCach
即使用第三方缓存来代替Mybatis的二级缓存,这里不详细介绍
四.Mybatis一二级缓存开启顺序
查询数据时,会按照以下顺序获取数据
- 二级缓存中是否有数据
- 一级缓存中是否有数据
- 查询数据库
理解:Mybatis的二级缓存要比一级缓存作用域大,但也存在一级缓存中有的数据,二级缓存中没有,如使用不同的SqlSession查询数据的时候,会把查询的数据放到一级缓存中(二级缓存中没有)。
今天的文章mybatisplus一级缓存和二级缓存_k8s和docker区别「建议收藏」分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/81542.html