论缓存机制:

1):mybatis 提供了缓存机制减轻数据库压力,提高数据库性能。
2):mybatis 的缓存分为两级:一级缓存、二级缓存
3):一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效。
4):二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的

一级缓存:

mybatis 的一级缓存是SqlSession级别的缓存,在操作数据库的时候需要先创建SqlSession会话对象,在对象中有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象无法访问。

具体流程:

1).第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来
2).第二次执行select会从缓存中查数据,如果select相同切传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
 
注意事项:
1):一级缓存的作用域是SqlSession范围的,当在同一个SqlSession中执行两次相同的 sql 语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存)中,
  第二次查询时会从缓存中获取数据,不再去底层进行数据库查询,从而提高了查询效率。需要注意的是:如果SqlSession执行了DML操作(insert、update、delete),
  并执行commit()操作,mybatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存数据中存储的是最新的信息,避免出现脏读现象。
 
2):当一个SqlSession结束后那么他里面的一级缓存也就不存在了,mybatis默认是开启一级缓存,不需要配置
 
3):mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。
 
例:-1242243203:1146242777:winclpt.bean.userMapper.getUser:0:2147483647:select * from user where id=?:19

二级缓存:

二级缓存是mapper级别的缓存,也就是同一个namespace的mappe.xml,当多个SqlSession使用同一个Mapper操作数据库的时候,得到的数据会缓存在同一个二级缓存区域,二级缓存默认是没有开启的。

需要在setting全局参数中配置开启二级缓存

conf.xml:

<settings>
<setting name="cacheEnabled" value="true"/>默认是false:关闭二级缓存
<settings>

在userMapper.xml中配置:

<!--在当前内部Mapper中打开二级缓存-->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
<!--引用全局缓存配置文件-->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
当前 mapper下所有语句开启二级缓存
这里配置了一个LRU缓存,并每隔60秒刷新,最大存储512个对象,而却返回的对象是只读的。
 
cache元素用来开启当前mapper的namespace下的二级缓存,该元素的属性设置如下:
flushInterval:
  刷新间隔,可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段,默认情况下是不设置的,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
 
size:
  缓存数目,可以被设置为任意正整数,要记住你的缓存对象数目和你运行环境可用内存资源数目,默认值是1024.
 
readOnly:
  只读,属性可以被设置为true或false,只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。
  这提供了很重要的性能优势,可读写的缓存会返回缓存对象的拷贝(通过序列化),这会慢一些,但是安全,因此默认是false。
 
eviction:收回策略,默认为LRU,有如下几种:
  LRU:最近最少使用的策略,移除最长时间不被使用的对象。
  FIFO:先进先出策略,按对象进入缓存的顺序来移除它们。
  SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象。
  WEAK:弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象。
 
若想禁用当前select语句的二级缓存,添加useCache="false"修改如下:
<select id="getCountByName" parameterType="java.util.Map"
resultType="INTEGER" statementType="CALLABLE" useCache="false">
具体流程:
  1).当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存
  2).当另一个sqlsession执行select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能。
 
注意事项一:
  1).如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前mapper缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
 
  2).mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。
 
注意事项二:
  1):使用二级缓存时,与查询结果映射的java对象必须实现java.io.Serializable接口的序列化和反序列化操作,如果存在父类,其成员都需要实现序列化接口,
    实现序列化接口是为了对缓存数据进行序列化和反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存,有可能是硬盘或者远程服务器。
 
例:-1242243203:1146242777:winclpt.bean.userMapper.getUser:0:2147483647:select * from user where id=?:19

全局配置文件:

ehcache.xml:

<ehcache>

    <!--临时文件目录  可以自己设置-->
<diskStore path="java.io.tmpdir"/> <!--
maxElementsInMemory:在内存中最大的存储量
eternal:是否在内存中永远不销毁
timeToIdleSeconds:在缓存中闲置多少时间之后销毁,默认单位是S
timeToLiveSeconds:在缓存中存活多少时间之后销毁,无论是否有人使用,默认单位是S
overflowToDisk:当缓存满的时候是否保存到磁盘中
diskPersistent:磁盘中的文件是否永久保存
diskExpiryThreadIntervalSeconds:检测线程运行时间间隔!默认单位是S *******************************************************
memoryStoreEvictionPolicy : 缓存清理策略
1.LRU (least recently used) 最近最少使用
每个缓存的元素都有一个时间戳,当缓存容量满的时候,需要腾出来新位置给新缓存元素,
这时候,会比较时间戳然后删除符合条件的缓存元素 2.LFU (least frequently used )最少使用
一直以来最少使用的缓存元素,缓存元素中有一个hit值,hit值最少的将会清除! 3.FIFO(first in first out) 先进先出
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>

参考:

demo:

END:

  对于MyBatis 缓存的内容仅做了解即可,因为面对一定规模的数据量,内置的Cache 方式就派不上用场了;并且对查询结果集做缓存并不是MyBatis 框架擅长的,它专心做的应该是SQL 映射。
  所以采用 OSCache 、Memcached 等专门的缓存服务器来做更为合理。
 

分享知识-快乐自己:Mybatis缓存机制的更多相关文章

  1. mybatis缓存机制

    目录 mybatis缓存机制 Executor和缓存 一级缓存 小结 二级缓存 小结 mybatis缓存机制 mybatis支持一.二级缓存来提高查询效率,能够正确的使用缓存的前提是熟悉mybatis ...

  2. 聊聊MyBatis缓存机制【美团-推荐】

    聊聊MyBatis缓存机制 2018年01月19日 作者: 凯伦 文章链接 18778字 38分钟阅读 前言 MyBatis是常见的Java数据库访问层框架.在日常工作中,开发人员多数情况下是使用My ...

  3. 《深入理解mybatis原理4》 MyBatis缓存机制的设计与实现

    <深入理解mybatis原理> MyBatis缓存机制的设计与实现 本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存 ...

  4. Mybatis缓存机制及mybatis的各个组成部分

    Mybatis 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 ...

  5. 聊聊MyBatis缓存机制

    https://tech.meituan.com/mybatis_cache.html 前言 MyBatis是常见的Java数据库访问层框架.在日常工作中,开发人员多数情况下是使用MyBatis的默认 ...

  6. 【转】MyBatis缓存机制

    转载:https://blog.csdn.net/bjweimengshu/article/details/79988252. 本文转载自公众号 美团技术点评 前言 MyBatis是常见的Java数据 ...

  7. MyBatis 缓存机制(十三)

    什么是缓存 缓存就是内存中的一个对象,用于对数据库查询结果的保存,用于减少与数据库的交互次数从而降低数据库的压力,进而提高响应速度. MyBatis 缓存机制原理 Mybatis 缓存机制原理是将第一 ...

  8. 开源框架是如何使用设计模式的-MyBatis缓存机制之装饰者模式

    写在前面 聊一聊MyBatis是如何使用装饰者模式的,顺便回顾下缓存的相关知识,可以看看右侧目录一览内容概述. 装饰者模式 这里就不了它的概念了,总结下就是套娃.利用组合的方式将装饰器组合进来,增强共 ...

  9. MyBatis缓存机制-二级缓存

    MyBatis二级缓存是基于namespace级别的缓存. 1.MyBatis的缓存机制整体设计以及二级缓存的工作模式 如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executo ...

随机推荐

  1. 身份证识别接口编写的JAVA调用示例

    此java文章是基本聚合数据证件识别接口来演示,基本HTTP POST请求上传图片并接收JSON数据来处理. 使用前你需要通过 https://www.juhe.cn/docs/api/id/153 ...

  2. java调试工具jdb

    Finds and fixes bugs in Java platform programs. Synopsis jdb [options] [classname] [arguments] optio ...

  3. Android源代码解析之(六)--&gt;Log日志

    转载请标明出处:一片枫叶的专栏 首先说点题外话,对于想学android framework源代码的同学,事实上能够在github中fork一份,详细地址:platform_frameworks_bas ...

  4. jquery方法

    $.inArray(被判断的量,ArrayName);  如果存在返回索引值,如果不存在返回-1 $.unique() 数组去重   根据去重前后的长度,判断是否有重复 $.each(被遍历的数组,f ...

  5. (七)jQuery中的DOM操作

    一.jQuery的DOM操作 (1)查找节点: 查找元素节点: 1. 获取指定的标签节点 $(“上级标签 标签:eq(“标签索引”) ;  如:var li = $("ul li:eq(2) ...

  6. DCDC电路电感和电容啸叫的原因

    电感啸叫原因 如果耳朵能听到啸叫(吱吱声),可以肯定电感两端存在一个20HZ-20KHZ(人耳范围)左右的开关电流. 例如DC-DC电路的电感啸叫,由于负载电流过大 DC内部有一个限流保护电路,当负载 ...

  7. Scrapy安装向导

    原文地址 https://doc.scrapy.org/en/latest/intro/install.html 安装Scrapy Scrapy运行在python2.7和python3.3或以上版本( ...

  8. android开发系列之视频断点续传

    今天在这篇博客里面,我想说说自己在这几天遇到的一个棘手的问题,就是视频断点续传的问题.其实这在我们开发中是一个很常见的应用场景,比如视频.音频.pdf等相关的文档.如果之前没有接触过的话,你也许会被这 ...

  9. GenericServlet 、Servlet和httpServler他们之间的关系

    1.GenericServlet类是所有Servlet类的祖先类. 2.HttpServlet类继承了GenericServlet类. 3.Servlet有两个非常重要的的对象,可以说是java we ...

  10. 搭建私有Nuget仓库

    使用Nexus搭建私有Nuget仓库 https://www.cnblogs.com/Erik_Xu/p/9211471.html 前言 Nuget是ASP .NET Gallery的一员,是免费.开 ...