计算机中内存和硬盘都是用来存储数据的,一个是临时存储,一个是持久化存储
MyBatis缓存机制
MyBatis缓存机制:
将从硬盘中查询的数据,存储到MyBatis缓存中(也就是内存中),如果下一次查询的SQL语句一样,那么不再读取硬盘,而是直接从缓存中读取数据;目的:减少IO,提高查询效率;
换句话说:将select语句的查询结果放到缓存(内存)当中,下一次还是这条select语句的话,直接从缓存中取,不再查数据库。一方面是减少了IO。另一方面不再执行繁琐的查找算法,效率大大提升;
常见缓存技术:
mybatis缓存包括:
一级缓存:将查询到的数据存储到SqlSession中
二级缓存:将查询到的数据存储到SqlSessionFactory中
或者集成其它第三方的缓存:比如EhCache【Java语言开发的】、Memcache【C语言开发的】等
补充:
1、缓存只针对于DQL语句,也就是说缓存机制只对应select语句
2、SqlSession、SqlSessionFactory这两个对象的生命周期:SqlSessionFactory是一个数据库只有一个,所以代表整个环境;所以二级缓存它的范围更大,代表整个数据库;一级缓存只是针对当前的SQL会话;
一级缓存
定义:一级缓存默认是开启的,不需要做任何配置
原理:只要使用同一个SqlSession对象执行同一条SQL语句,就会走缓存
什么情况下不走"一级缓存"?
- 第一种:不同的SqlSession对象
- 第二种:查询条件变化了
什么情况下"一级缓存"失效?
一级缓存失效情况包括两种:
- 第一种:第一次查询和第二次查询之间,手动清空了一级缓存 sqlSession.clearCache();
- 第二种:第一次查询和第二次查询之间,执行了增删改操作。【这个增删改和哪张表没有关系,只要有insert delete update操作,一级缓存就失效。】原因:只要执行增删改都会清空一级缓存,目的:保证数据查询出来是真实的,即缓存中的查询数据和数据库中的数据是一致的;
二级缓存
首先,二级缓存的范围是SqlSessionFactory
"二级缓存"起作用,前提条件:
1、第一个:<setting name="cacheEnabled" value="true"> 全局设置,默认就是true,不用管
2、第二个:SQL配置文件中添加<cache/>
3、第三个:pojo类实现Serializable接口
4、第四个(关键):如果一级缓存不关闭,那么默认会一直从一级缓存中获取数据;因为,只有一级缓存关闭,数据才会从一级缓存放到二级缓存中去;此时,只要是同一个SqlSessionFactory,就会走二级缓存;
补充:
1.每一个sqlSession对象都对应一个一级缓存
2.只有关闭sqlSession对象之后,查询数据才会从一级缓存放到二级缓存
3.Cache Hit Ratio:缓存命中率
二级缓存的失效:
只要两次查询之间出现了增删改操作。二级缓存就会失效。【一级缓存也会失效】
一级缓存和二级缓存优先级?
二级缓存>一级缓存>数据库
MyBatis集成EhCache
集成EhCache是为了代替mybatis自带的二级缓存,一级缓存是无法替代的。
MyBatis对外提供了接口,也可以集成第三方的缓存组件;比如EhCache、Memcache等
EhCache是Java写的,Memcache是C语言写的,所以mybatis集成EhCache较为常见