MyBatis的二级缓存的设计原理

MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。本文将全面分析MyBatis的二级缓存的设计原理。

1.MyBatis的缓存机制整体设计以及二级缓存的工作模式

如上图所示,当开一个会话时,一个 SqlSession对象会使用一个 Executor对象来完成会话操作, MyBatis的二级缓存机制的关键就是对这个 Executor对象做文章。如果用户配置了" cacheEnabled=true",那么 MyBatis在为 SqlSession对象创建 Executor对象时,会对 Executor对象加上一个装饰者: CachingExecutor,这时 SqlSession使用 CachingExecutor对象来完成操作请求。 CachingExecutor对于查询请求,会先判断该查询请求在 Application级别的二级缓存中是否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的 Executor对象来完成查询操作,之后 CachingExecutor会将真正 Executor返回的查询结果放置到缓存中,然后在返回给用户。

CachingExecutor是 Executor的装饰者,以增强 Executor的功能,使其具有缓存查询的功能,这里用到了设计模式中的装饰者模式,

CachingExecutor和 Executor的接口的关系如下类图所示:

2 . MyBatis二级缓存的划分

MyBatis并不是简单地对整个 Application就只有一个 Cache缓存对象,它将缓存划分的更细,即是 Mapper级别的,即每一个Mapper都可以拥有一个 Cache对象,具体如下:

a.为每一个Mapper分配一个Cache缓存对象(使用<cache>节点配置);

b.多个Mapper共用一个Cache缓存对象(使用<cache-ref>节点配置);

a.为每一个Mapper分配一个Cache缓存对象(使用<cache>节点配置)

MyBatis将 Application级别的二级缓存细分到 Mapper级别,即对于每一个Mapper.xml,如果在其中使用了 <cache> 节点,则 MyBatis会为这个 Mapper创建一个 Cache缓存对象,如下图所示:

注:  上述的每一个Cache对象,都会有一个自己所属的namespace命名空间,并且会将Mapper的 namespace作为它们的ID;

b.多个Mapper共用一个Cache缓存对象(使用<cache-ref>节点配置)

如果你想让多个 Mapper公用一个 Cache的话,你可以使用 <cache-ref namespace="">节点,来指定你的这个 Mapper使用到了哪一个 Mapper的 Cache缓存。

3. 使用二级缓存,必须要具备的条件

MyBatis对二级缓存的支持粒度很细,它会指定某一条查询语句是否使用二级缓存。

虽然在 Mapper中配置了 <cache>,并且为此 Mapper分配了 Cache对象,这并不表示我们使用 Mapper中定义的查询语句查到的结果都会放置到 Cache对象之中,我们必须指定 Mapper中的某条选择语句是否支持缓存,即如下所示,在 <select> 节点中配置 useCache="true", Mapper才会对此 Select的查询支持缓存特性,否则,不会对此 Select查询,不会经过 Cache缓存。如下所示, Select语句配置了 useCache="true",则表明这条 Select语句的查询会使用二级缓存。

 <select id="selectByMinSalary" resultMap="BaseResultMap" parameterType="java.util.Map" useCache="true">

总之,要想使某条 Select查询支持二级缓存,你需要保证:

1.  MyBatis支持二级缓存的总开关:全局配置变量参数   cacheEnabled=true

   2. 该select语句所在的Mapper,配置了<cache> 或<cached-ref>节点,并且有效

   3. 该select语句的参数 useCache=true 

4. 一级缓存和二级缓存的使用顺序

请注意,如果你的 MyBatis使用了二级缓存,并且你的 Mapper和 select语句也配置使用了二级缓存,那么在执行 select查询的时候, MyBatis会先从二级缓存中取输入,其次才是一级缓存,即 MyBatis查询数据的顺序是:

       二级缓存    ———> 一级缓存——> 数据库

5. 二级缓存实现的选择

MyBatis对二级缓存的设计非常灵活,它自己内部实现了一系列的 Cache缓存实现类,并提供了各种缓存刷新策略如 LRU,FIFO等等;另外, MyBatis还允许用户自定义 Cache接口实现,用户是需要实现 org.apache.ibatis.cache.Cache接口,然后将 Cache实现类配置在 <cache  type="">节点的 type属性上即可;除此之外, MyBatis还支持跟第三方内存缓存库如 Memecached的集成,总之,使用 MyBatis的二级缓存有三个选择:

1.MyBatis自身提供的缓存实现;

        2. 用户自定义的Cache接口实现;

        3.跟第三方内存缓存库的集成;

6.  MyBatis自身提供的二级缓存的实现

MyBatis自身提供了丰富的,并且功能强大的二级缓存的实现,它拥有一系列的 Cache接口装饰者,可以满足各种对缓存操作和更新的策略。

MyBatis定义了大量的 Cache的装饰器来增强 Cache缓存的功能,如下类图所示。

对于每个 Cache而言,都有一个容量限制, MyBatis各供了各种策略来对 Cache缓存的容量进行控制,以及对 Cache中的数据进行刷新和置换。 MyBatis主要提供了以下几个刷新和置换策略:

LRU:(Least Recently Used),最近最少使用算法,即如果缓存中容量已经满了,会将缓存中最近做少被使用的缓存记录清除掉,然后添加新的记录;

FIFO:(First in first out),先进先出算法,如果缓存中的容量已经满了,那么会将最先进入缓存中的数据清除掉;

Scheduled:指定时间间隔清空算法,该算法会以指定的某一个时间间隔将 Cache缓存中的数据清空;

6. 写在后面(关于涉及到的设计模式) 

在二级缓存的设计上,MyBatis大量地运用了装饰者模式,如CachingExecutor, 以及各种Cache接口的装饰器。关于装饰者模式,读者可以阅读相关资料,我的另外一篇博文    Java 设计模式 装饰者模式供读者参考。

本文只是讲述MyBatis二级缓存的基本原理,关于自定义二级缓存和与第三方内存库的集成,将在后续的文章中再做讨论,敬请关注!

作者的话

本文是《深入理解mybatis原理》系列的其中一篇,如果您有兴趣,请关注该系列的其他文章~

觉得本文不错,顺手点个赞哦~~您的鼓励,是我继续分享知识的强大动力!

如果您觉得有不妥或者错误的地方,还请您不吝指教!

-----------------------------------------------------------------------------------------------------------------------------------------

本文源自  http://blog.csdn.net/luanlouis/,如需转载,请注明出处,谢谢!

mybatis专栏

http://blog.csdn.net/column/details/mybatis-principle.html?page=1

时间: 2024-10-11 07:28:03

MyBatis的二级缓存的设计原理的相关文章

《深入理解mybatis原理》 MyBatis的二级缓存的设计原理

MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及二级缓存的工作模式 如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章.如果用户配置了"cacheEnabled=true",那么MyBatis在为SqlSession

《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理

<深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及二级缓存的工作模式 如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章.如果用户配置了"cache

mybatis整合Redis实现二级缓存

Mybatis整合ehcache实现二级缓存 导入相关依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!--mybatis与ehcache整合--

二级缓存和配置原理

二级缓存是进程或集群范围内的缓存,可以被所有的Session共享 二级缓存是可配置的插件 01.二级缓存的配置使用(ehcache缓存) *1.引入如下jar包. ehcache-1.2.3.jar  核心库 backport-util-concurrent.jar commons-logging.jar *2.配置Hibernate.cfg.xml开启二级缓存 <property name="hibernate.cache.use_second_level_cache">

二级缓存配置和原理

二级缓存是进程或集群范围内的缓存,可以被所有的Session共享 二级缓存是可配置的插件 01.二级缓存的配置使用(ehcache缓存) *1.引入如下jar包. ehcache-1.2.3.jar  核心库 backport-util-concurrent.jar commons-logging.jar *2.配置Hibernate.cfg.xml开启二级缓存 <property name="hibernate.cache.use_second_level_cache">

mybatis结合redis实战二级缓存(六)

之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSCache.Hazelcast结合使用.二级缓存相关的源码分享请参考<Mybatis源码分析之Cache二级缓存原理>.我们通过两种方式来实战,一种是自己编写缓存.另外一种是官方给出的demo地址:http://www.mybatis.org/redis-cache/ 一:自定义mybatis缓存

SpringMVC mybatis or hibernate ehcache二级缓存maven非和maven版本

获取[下载地址]   QQ: 313596790   [免费支持更新] 支持三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 代码生成器(开发利器);       增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成    就不用写搬砖的代码了,生成的放到项目里,可以直接运行 B 阿里巴巴数据库连接

【企业框架源码】 SpringMVC mybatis or hibernate ehcache二级缓存maven非和maven版本【websocket即时通讯】

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单;freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Drui

maven非maven版本 SpringMVC mybatis or hibernate ehcache二级缓存【websocket即时通讯】【企业级框架源码】

开发快报: 页面打印功能,websocket 强制下线功能,玩转websocket技术  [金牌]获取[下载地址]   QQ: 313596790A 代码生成器(开发利器);     增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成   就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩展性.稳定性和性能方面都