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使用相同的MaperSQL语句操作数据库,获得的数据将有一个二级缓存区,也使用HashMap进行数据存储。
与一级缓存相比,二级缓存的范围更大,多个SqlSession可用于二级缓存。
二级缓存是跨SqlSession。
二级缓存是多个SqlSession共享,其作用域是Maper的同一namespace,不同的SqlSession两次执行同一namespace下的Sql语句,参数相等,第一次执行成功后,将数据保存到二次缓存中,第二次可直接从二次缓存中取出数据,同步生命周期和应用程序。
具体工作流程如下所示。
我们来思考一个问题,如果打开二级缓存,二级缓存应该在一级缓存前工作还是在一级缓存后工作?二级缓存在哪里维护??
作为一种更广泛的缓存,它必须是在SqlSession的外层,否则不可能被多个SqlSession共享。一级缓存在SqlSession内部,所以第一个问题必须在一级缓存前工作,也就是说,只有当你不能得到二级缓存时,你才会在会话中得到一级缓存。
第二个问题,二次缓存在哪个对象中维护?如果要跨会话共享,SqlSession本身和它的basexecutor已经不能满足需求,所以我们应该在baseexecutor之外创建一个对象。
实际上MyBatis使用装饰类进行维护,即CachingExecutor。如果使用二级缓存,MyBatis在创建Executor时会装饰Executor。对于查询请求,cachingexecutor将判断二次缓存是否有缓存结果,如果有,则直接返回;如果没有,则委托给真正的executor实现类,如simpleeexecutor进行查询,然后进入一级缓存过程,最后将结果缓存并返回给用户。
与一级缓存相比,Mybatis的二级缓存实现了Sqlsession之间缓存数据的共享,粒度更细,可以达到namespace级别,通过cache接口实现不同类别的组合,对cache的可控性更强。Mybatis在多表查询中,很可能会出现脏数据,存在设计缺陷,二级缓存的安全使用条件更加苛刻。在分布式环境中,由于默认MyBatis Cache的实现是基于本地的。在分布式环境中,读取脏数据是不可避免的。MybatisCache接口需要集中缓存来实现,具有一定的开发成本。直接使用Redis、Memcached等分布式缓存可能成本更低,安全性更高。
看完这篇文章,大家都对了MyBatis一、二级缓存的基本概念有一定的理解,虽然这只是对MyBatis缓存机制一点简单的理解。但是,我们已经掌握了不积小步,千里之外。MyBatis最基本的知识可以更全面地学习MyBatis,当然,如果你认为这个知识不全面,你也可以快速开始MyBatis视频课程,使学到的知识更加扎实。