查询缓存的使用,主要是为了提高查询访问速度。将用户对同一数据的重复查询过程简化,不再每次均从数据库查询获取结果数据,从而提高访问速度。
MyBatis 的查询缓存机制,根据缓存区的作用域(生命周期)可划分为两种:一级查询
缓存与二级查询缓存。
一级查询缓存
MyBatis 一级查询缓存是基于 org.apache.ibatis.cache.impl.PerpetualCache 类的 HashMap 本地缓存,其作用域是 SqlSession。在同一个 SqISession 中两次执行相同的 sql 查询语句,第一次执行完毕后,会将查询结果写入到缓存中,第二次会从缓存中直接获取数据,而不再到数据库中进行查询,从而提高查询效率。
当一个 Sq|Session 结束后,该 SqlSession 中的一级查询缓存也就不存在了。myBatis 默认一级查询缓存是开启状态,且不能关闭。
执行原理示意图
执行流程图
项目:MyBatis_Cache_SqlSession。在以前动态 SQL 项目的基础上修改即可。
一级查询缓存的存在性证明
(1)修改测试类
![]()
(2)查看控制台
执行完后,发现只执行了一次从 DB 中的查询,第二次的查询结果是直接输出的。说明,第二次是从 SqlSession 缓存中读取的。
![]()
从缓存读取数据的依据是 Sql 的 id
一级缓存缓 存的是相同 Sql 映射 id 的查询结果,而非相同 Sql 语句的查询结果。因为 myBatis 内部对于查询缓存,无论是一级查询缓存还是二级查询缓存,其底层均使用一个 HashMap 实现:key 为 Sql 的 id 相关内容,value 为从数据库中查询出的结果。
(1)修改映射文件
在映射文件中对某一个<select/>标签进行完全复制,然后修改一下这个 SQL 映射的 id。也就是说,这两个 SQL 映射除了 id 不同,其他均是相同的,即查询结果肯定是相同的。
![]()
(2)修改 Dao 接口
![]()
(3)修改测试类
![]()
(4)查看控制台
查看控制台,发现第二次查询结果与第一次的完全相同,但第二次查询并没有从缓存中读取数据,而是直接从 DB 中进行的查询。这是因为从缓存读取数据的依据是查询 SQL 的映射 id,而非查询结果。
![]()
增删改对一级查询缓存的影响
增、删、改操作,无论是否进行提交 sqlSession.commit(),均会清空一级查询缓存,使查询再次从 DB 中 select。
(1)修改测试类
![]()
(2)查看控制台
![]()
网友评论