人世仙家本自殊,何须相见向中途。惊鸿瞥过游龙去,漫恼陈王一事无。
嗨,大家好,我是洛神,性别男。一个来自快乐星球的程序员。
欢迎大家专注我的公众号【程序员洛神】,不仅分享技术,还会分享生活趣事、体育。

前言

话说前几日,在群里摸鱼时,看到一个可怜楚楚的小妹妹在群里被一帮抠脚大汉围殴,一看,原来是在讨论Mybatis一二级缓存,此时小妹妹正处于下风,英俊潇洒的洛神怎会弃她于不顾?自然是奋不顾身冲上前去挡在好妹妹面前,一边Google一边和这帮大汉对线,奈何洛神我双拳难敌四手,搞得我是左右为男。

正当洛神快要被降伏之际(等等,降伏不是形容妖怪的迈?)。突然一道金光从天而降,让人无法睁眼直视。金光散去之后,地上安静的躺着一本古老的书籍,洛神走上前去,仔细一看,我尼玛,这不是传说中,大禹治水留下的《洛神说看完这篇Mybatis一二级缓存要是你还不会,就送你个学妹!skr》吗?倘若我掌握了这本书百分之一的精髓,这帮匹夫岂能与我为敌?说时迟那时快,洛神盘坐在地上,气沉丹田,运气至全身,慢慢的翻开了这本书:

Mybatis一级、二级缓存

缓存的作用就不多说了,肯定就是为了减少数据库操作次数,降低数据库压力,将查询结果放到缓存中,下次查询直接取结果,提升查询性能。
mybatis是默认开启一级缓存的,二级缓存默认是关闭的。

一级缓存

一级缓存的存储方式是使用了HashMap的数据结构,key值的组成结构:key值本身的hashCode值+sqlid(由数据库生成)+sql语句本身。 value值则是执行结束后映射出来的Java对象。

一级缓存的作用域是一个SqlSession内部,当我们执行查询后,查询的结果会存入到SqlSession为我们提供的一个map结构中,当我们再次查询同样的数据的时候,mybatis会先去sqlsession中查询,如果有就直接存在,没有再去查数据库。但是要注意的是,一级缓存是依赖于SqlSession对象的,当SqlSession消失后,一级缓存也就消失了。

某些情况下SqlSession都会被重建:

1.如果在代码中使用mybatis,没有使用Spring事务,每次请求数据库,都会新建一个SqlSession,所以这个时候一级缓存时没作用的。
2.调用了SqlSession的修改、添加、删除、commit()、close()方法的时候,一级缓存也会被清空。

有的同学可能对图中绿不拉机的东东比较陌生,我顺带着介绍一下介个东东:

Executor是Mybatis的核心接口,所有的对数据库的增删改查动作都是通过这个接口完成的。

Executor的工作内容主要有如下几项:
1.对一级、二级缓存进行处理。
2.用它来获取数据库的连接。
3.创建statement对象。
4.拿着SQL去数据库执行。
5.将数据库返回的结果进行处理。

来,掌声欢迎整整齐齐的Executor一家人闪亮登场! 啪啪啪啪啪啪~~~~~

Executor中定义了执行器的基本操作(增删改查以及事务的提交、回滚、清空缓存等)

接下来是BaseExecutor,它是一个抽象类,也是定义了一些执行器的基本操作。它是除了CachingExecutor之外所有executor的基类(毕竟CachingExecutor是负责二级缓存的,肯定是要面子的啦)。它主要负责处理一级缓存,下图中的localCache属性就代表着一级缓存。当你使用这个executor来做数据处理的时候,如果是查询,它会先看一级缓存里有没有你要查的数据,如果有,就直接返回,如果没有,就会调用下面的子类的方法去获取数据,然后缓存起来(简称白嫖,像你们一样!)。同样的,当SQL是增删改的话,也会清空对应的一级缓存。

BaseExecutor下面有三个子类,我一一简单介绍下,不展开叙述:

1.SimpleExecutor
整个家族里逻辑最简单的一个执行器,拿到sql直接交给StatementHandler去执行,没有额外的骚操作。

2.BatchExecutor
批处理的执行器,通过批量操作来提升执行性能。它的查询逻辑和SimpleExecutor是一样的,但是对于需要增改的SQL,它不会直接执行,而是放到批次里,等到提交的时候统一执行(JDBC的batch操作)。

3.ReuseExecutor
按照语义理解,可再次使用的执行器,指的是statement对象可以再次使用,内部会通过维护一个HashMap来保存statement对象(Key是需要执行的SQL语句,Value则是生成的statment对象),防止statement不断的重建,以此来提升性能。

CachingExecutor
这个是用来管理二级缓存的执行器,它采用了静态代理模式,通过代理一个Executor对象来执行操作。如果发现二级缓存中没有需要查询的数据,那么它就是把这个请求转交给其他的executor来处理,如果它发现要处理的SQL是增删改类型的,那么就会清空整个二级缓存。

你想使用哪个执行器,都是可以在配置文件中进行配置的。

<settings><!--SIMPLE、REUSE、BATCH--><setting name="defaultExecutorType" value="SIMPLE"/>
</settings>

Mybatis如何判断两次查询是否是完全相同的查询?

介个问题问得好,心里能有这个疑问的说明自己在主动思考了,mybatis对于两次查询是否是完全相同的判断,需要满足以下几个条件。

1.传入的statementId要相同。(statement我就不用多说了把,Java就是通过它向数据库发送SQL语句)
2.查询时想要查询的结果的范围要相同。
3.最终传递给JDBC进行解析的sql串要完全相同。
当这个几个条件同时满足后,mybatis就会判定这是同一个查询,就会直接去缓存中查询。

二级缓存

图很重要!先把图给我看十遍!(转载图片请注明出处,感谢)

二级缓存数据应用级缓存,默认是关闭的,开启二级缓存后,mybatis要求返回的必须是可以被序列化的实体。

二级缓存的作用域是同一个nameSpace(别问我nameSpace是啥哈!自己打开自己写的mapper.xml文件,第一行里面就写了),整个nameSpace里的所有语句,都共用同一个cache,换句话说 ,二级缓存被多个sqlSession对象共享。

当执行update/insert等修改方法时,整个作用域的缓存就会失效并重新刷新。

开启二级缓存的方法:
//mybatis配置文件中开启

<settings>     <setting name="cacheEnabled" value="true"/>
</settings>
<cache 有具体的配置项信息eviction  缓存的回收策略,默认是LRU(移除最长时间没有使用的对象) 还有例如FIFO(先进先出,按照对象进入缓存的时间来依次移除) SOFT、WEAKflushInterval  设置缓存多久刷新一次  默认是不清空的size  设置缓存里可以存放多少个元素readOnly  设置是否为只读    设置为true  速度最快  但是不安全 因为maybatis会直接将数据在缓存中的引用交给你false的话速度慢  mybatis会通过序列化和反序列化copy一份数据给你/>

一般是不建议使用二级缓存的,因为二级缓存有几个比较大的缺陷,想象一个业务场景:

数据库存放了10000个商品让用户抢购,这个时候访问量肯定是比较大的,所以首先考虑到的肯定就是将商品放入缓存中,那么,假如我们启用了二级缓存后,会发生什么情况呢,第一次查询将数据放到了缓存中,当用户抢购了商品A后,肯定是要刷新商品A的库存的吧,这个时候,如果我刷新缓存,那么,所有商品的信息都会被刷新了,因为二级缓存的作用域是整个nameSpace,本质上就是要死大家一块儿死。所以这个二级缓存很极端的嘞,大家还是谨慎使用。

还有就是,关于脏数据的问题:

洛神一顿操作写了一个完美的SQL

select  a,b,c,d  from  table1   left join table2  on  table1.id = table2.id

可以看出来,洛神是关联两张表查询的(a b字段属于table1 c d字段属于table2),假设哈,这个table1的业务操作都在table1Mapper.xml中 table2的业务操作都啊在table2Mapper.xml中。

我开启了二级缓存,先在table1Mapper.xml中执行了上面的那个SQL,好了,abcd的数据都被缓存起来了,然后,我在table2Mapper.xml中,更新了c和d字段的数据,然后我又在table1Mapper.xml中执行了那个SQL,呕吼,发现问题了吗?由于abcd的数据已经被缓存了,所以我根本感知不到你把c和d的数据改了啊,那不就完犊子了,查出来的数据不就是脏数据了。所以牵扯到联表查询的业务,不要使用二级缓存。

所以在实际业务场景中,对于有缓存需求的功能,都是优先使用Memcache或者redis等缓存中间件来做缓存。一是方便扩容,二是缓存中间件的功能比mybatis的二级缓存强大很多。

诶?那我是不是又可以水一篇Redis和Memcache的文章了?

卧槽,这本书写的,真的是妙蛙种子吃着妙脆角进了米奇妙妙屋,秒到家了!早有幸能看到如此神作,我洛某人何至于此境地,待老夫这就杀他们个片甲不留!对了!我还要将这本神作刻下来,留给世人传颂!
看完这本书你要是还学不会,老夫送你一个学妹!

反正洛神看完这篇文章是湿了,你们呢?

洛神唠点心里话

最近发现爱上了写文章了,也不是为了多少人看,感觉能把自己学习到的,自己知道的东西用比较贯通的语言表达出来,然后每天夜深人静的时候偷偷在被窝里来回欣赏(气氛逐渐变态。。。),看到自己发布在博客上的文章被几百人几千人的浏览,真的感觉挺自豪的,自己写的哪怕能对其他人有一丢丢的帮助,那也算是善事一件啊。

最近几天逛论坛的时候,发现好多人都问,怎么通过写文章变现?我觉得这个问题不能一视同仁。如果你想把它当作一个职业,那你需要具备良好的文字功底,能挖掘用户群众的需求,并且还要具备一定的运营能力,而不是简简单单的每天写写文章发一发。如果你写文章的初心只是为了记录自己的成长,那就别太在乎这些,努力不断学习,不断在工作中打磨自己的能力,等到哪天自己站在这个行业更高的角度的时候,当初你羡慕的东西,都会慢慢归属于你了。
朋友请记住,你若盛开,花香自来。

人世仙家本自殊,何须相见向中途。惊鸿瞥过游龙去,漫恼陈王一事无。我是洛神,我们下期见。

洛神说看完这篇Mybatis一二级缓存要是你还不会,就送你个学妹!skr相关推荐

  1. 我就不信看完这篇你还搞不懂信息熵

    我就不信看完这篇你还搞不懂信息熵 https://mp.weixin.qq.com/s/7NrB0UtmELXD3UNO3C6jGA 让我们说人话!好的数学概念都应该是通俗易懂的. 信息熵,信息熵,怎 ...

  2. python装饰器原理-看完这篇文章还不懂Python装饰器?

    原标题:看完这篇文章还不懂Python装饰器? 1.必备 2.需求来了 初创公司有N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作.redis调用.监控API等功能.业务部门 ...

  3. 看完这篇文章之后,终于明白了编译到底怎么回事。

    看完这篇文章之后,终于明白了编译到底怎么回事. 1 对于同一个语句,有如下三种:高级语言.低级语言.机器语言的表示 C语言  a=b+1; 汇编语言  mov -0xc(%ebp),%eax add ...

  4. linux shell find depth,搞定 Linux Shell 文本处理工具,看完这篇集锦就够了

    原标题:搞定 Linux Shell 文本处理工具,看完这篇集锦就够了 Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替.既然是基本功,那就需要掌握,毕 ...

  5. 看完这篇文章之后,终于明白了编译到底怎么回事

    看完这篇文章之后,终于明白了编译到底怎么回事. 1 对于同一个语句,有如下三种:高级语言.低级语言.机器语言的表示 C语言  a=b+1; 汇编语言  mov -0xc(%ebp),%eax add ...

  6. html5 游戏前景怎么样,独家 HTML5游戏目前究竟怎么样?看完这篇文章,你或许会清晰很多...

    原标题:独家 HTML5游戏目前究竟怎么样?看完这篇文章,你或许会清晰很多 文/DataEye CEO 汪祥斌 从5月份白鹭的10亿估值,到最近悟空间.山水地.火缘步甲的千万级以上的融资,我们可以感受 ...

  7. 手把手教你完成CSDN对接百度统计 看完这篇文章你还不会对接 欢迎您提刀顺着网线来砍我!!!!

    大家好,我是:じ☆ve朽木,开发经验都是一步一步慢慢积累的,没有谁生来就具有的,只要我们付出了努力,肯定就会有收获!进入我的博客,带你了解Java知识,js小技巧,带你玩转高端物联网.博客地址为:じ☆ ...

  8. 看完这篇文章保你面试稳操胜券——React篇

    ✨ 进大厂收藏这一系列就够了,全方位搜集总结,为大家归纳出这篇面试宝典,面试途中祝你一臂之力!,共分为四个系列 ✨ 本 篇 为 < 看 完 这 篇 文 章 保 你 面 试 稳 操 胜 券 > ...

  9. 看完这篇文章保你面试稳操胜券——小程序篇

    ✨ 进大厂收藏这一系列就够了,全方位搜集总结,为大家归纳出这篇面试宝典,面试途中祝你一臂之力!,共分为四个系列 ✨ 本 篇 为 < 看 完 这 篇 文 章 保 你 面 试 稳 操 胜 券 > ...

最新文章

  1. python散点图点的大小-Java 学习之路
  2. Python3爬虫-01-简单网页爬取
  3. 成功解决基于VS2015(Visual Studio2015)编写C++程序调试时弹出窗口一闪而过的问题
  4. C#中对虚拟属性和抽象属性的重写,重写label实例
  5. 知识图谱最新权威综述论文解读:关系抽取
  6. 学术谱系树:来看看你导师的师承
  7. 基于用户的协同过滤推荐算法
  8. matlab里rem怎么表示,matlab的rem()和mod()函数
  9. mysql安全补丁,Oracle发布了本季安全补丁,包含了mysql在内的高危漏洞补丁
  10. 今晚9点!相约ISAC(6G通信感知一体化)在线研讨会!
  11. 管家婆财贸双全存货核算类型对应会计科目禁止删除
  12. Visual Studio 2017中找不到商业智能(Business Intelligence)模块 |
  13. win10关闭windows聚焦_一劳永逸 教你彻底关闭Win10广告显示
  14. 协议森林05 我尽力 (IP协议详解)
  15. 51nod-1299 监狱逃离(贪心)
  16. docker安装ElasticSearch8.1.0错误curl: (52) Empty reply from server的处理方法
  17. 什么是计算机使用及安全管理制度,安全管理制度
  18. 什么是MVC和MVVC,以及它们的区别
  19. HTML编写个人日记,HTML学习日记(1-基础)
  20. 怎么设计一个秒杀系统

热门文章

  1. 单元测试工具 BoundsChecker 【转载】
  2. ICT 2017 | 斑马网络郝飞:当汽车走进智联网时代
  3. ubuntu18.04安装redis教程
  4. 荷花定律计算过程c语言,有多少人败给了“荷花定律”
  5. Tomcat服务器启动Bug:Error running ‘Tomcat 9.0.37‘: Address localhost:1099 is already in use
  6. 设计模式笔记之二工厂方法模式
  7. Android 实现华为,小米的桌面角标(小红点)
  8. 携手易维帮助台,神州数码轻松搞定IT外包服务
  9. android button 图片 大小设置,android 中怎么控制ImageButton 上的图片与按钮大小的匹配...
  10. java的session问题