动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

初窥MyBatis缓存机制

07-01 17:48 206浏览
举报 T字号
  • 大字
  • 中字
  • 小字

MyBatis是常见的Java数据库访问层框架。缓存是一般ORM框架都会提供的功能, 目的就是提升查询的效率和减少数据库的压力。MyBatis缓存机制MyBatis的关键的组成部分,也是学习MyBatis的起点。

举个很简单的例子,当我们在调用sql语句的时候,同样一个内容,如果查询两次,就不必要从数据库中查询两次,可以在查询第一次后把数据暂时存在缓存区,这样减少java应用程序和数据库的交互次数,提高了运行效率。

下面为大家介绍MyBatis的缓存机制:

一、一级缓存

一级缓存是SqlSession级别,默认开启。并且不能关闭。(自带的,不用任何操作)

操作数据库时,需要创建SqlSession对象,在对象中有一个HashMap用于存储缓存数据;不同的SqlSession之间缓存数据区域是互不影响的。

一级缓存的作用域是SqlSession范围的,当在同一个SqlSession中执行两次相同的SQL语句时,第一次执行完,会将结果保存在缓存中,第二次查询时直接从缓存中获取。具体执行过程如下图所示。

 

我们来看看如何使用MyBatis一级缓存。开发者只需在MyBatis的配置文件中,添加如下语句,就可以使用一级缓存。共有两个选项,SESSION或者STATEMENT,默认是SESSION级别,即在一个MyBatis会话中执行的所有语句,都会共享这一个缓存。一种是STATEMENT级别,可以理解为缓存只对当前执行的这一个Statement有效。

 

每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。

MyBatis的一级缓存作用就是在同一个session过程中,将会对相同数据的存取不通过数据库,而是通过缓存机制提高效率,看测试代码:

使用一级缓存的时候,因为缓存不能跨会话共享,不同的会话之间对于相同的数据可能有不一样的缓存。在有多个会话或者分布式环境下,会存在脏数据的问题。如果要解决这个问题,就要用到二级缓存。

二、二级缓存

二级缓存Mapper级别,默认关闭,可以开启

多个SqlSession使用同一个Mapper的SQL语句操作数据库,得到的数据会存在二级缓存区,同样是使用HashMap进行数据储存。

相较一级缓存,二级缓存的范围更大,多个SqlSession可以公用二级缓存。

二级缓存是跨SqlSession的。

二级缓存是多个SqlSession共享的,其作用域是Mapper的同一个namespace,不同的SqlSession两次执行相同的namespace下的Sql语句,参数也相等,则第一次执行成功之后,会将数据保存到二级缓存中,第二次可直接从二级缓存中取出数据生命周期和应用同步

具体的工作流程如下所示。

 

我们来思考一个问题,如果开启了二级缓存,二级缓存是应该工作在一级缓存之前还是在一级缓存之后呢?二级缓存是在哪里维护的呢?

作为一个作用范围更广的缓存,它肯定是在SqlSession的外层,否则不可能被多个SqlSession共享。而一级缓存是在SqlSession内部的,所以第一个问题,肯定是工作在一级缓存之前,也就是只有取不到二级缓存的情况下,才会到一个会话中取一级缓存。

第二个问题,二级缓存存放在哪个对象中维护呢?要跨会话共享的话,SqlSession本身和它里面的BaseExecutor已经满足不了需求了,那我们应该在BaseExecutor之外创建一个对象。

实际上MyBatis用了一个装饰器的类来维护,就是CachingExecutor。如果启用了二级缓存,MyBatis在创建Executor的时候会对Executor进行装饰。CachingExecutor对于查询请求,会判断二级缓存是否有缓存结果,如果有就直接返回;如果没有,就委派交给真正的Executor实现类,比如SimpleExecutor来执行查询,再走到一级缓存的流程,最后把结果缓存起来,并且返回给用户。 

MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis,Memcached等分布式缓存可能成本更低,安全性也更高。

看完了本文之后,大家对MyBatis一二级缓存的基本概念有了一定的认识虽然这只是MyBatis缓存机制的一点简单的认识。但不积跬步无以至千里,我们掌握了MyBatis的最基本的知识,才能更加全面的学习MyBatis,当然如果觉得这个知识不全面的话,还可以快速上手MyBatis视频课程,让学到的知识更扎实。

0人推荐
共同学习,写下你的评论
0条评论
上善若水
程序员上善若水

16篇文章贡献85593字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

五分钟读懂UML类图

江湖人称小李白12-10 10:41

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消