本文是关于mybatis缓存模块设计的读后感,关于缓存的思考,关于mybatis的缓存源码详细分析在另一篇文章:https://www.cnblogs.com/gmt-hao/p/12448896.html,欢迎大家指教。

一般我们用到缓存的时候,只知道他很快,很强,还能持久,但是为什么他可以做到这些呢,有人会说这是天赋,遗传的,是的,你想的没错,确实是大佬们在构造这些的时候,赋予他这些能力,那今天我们就来剖析一下,大佬们干了啥,区区缓存就能这么厉害。

去大厂面试的时候,面试官总会喜欢问为什么,一开始,完全搞不懂我就去拧个螺丝,你问我造火箭怎么造我咋知道,后来在工作中遇到各种各样的问题,解决不了的时候,看着身边大佬们一层层点进去看源码分析问题的时候,瞬间觉得这多牛逼啊,或许一开始有动力看源码,了解为什么就是因为这个了吧(能装逼)。说回今天的主题-缓存,缓存在百度上的解释就是访问速度比一般随机存取存储器(RAM)快的一种高速存储器,其实对于我们而言就是一个访问速度特别快的数据库,一般而言是一种key-value形式存储的,因为便于查找,无论是类似redis还是我们自己程序中的,其实都是一个道理,他查找快的最大秘诀还是直接在内存中操作,但是由于现在互联网发展太快,大厂的用户量太大了,所以我们已经不能满足于此,那么我们怎么样找到对应的缓存的位置,更加是需要考量的,我们不由得想想,如果是我,那么该如何去设计一个缓存呢,或许能答出来的就是基于内存放到一个map当中读写了吧,那么mybatis作为一个优秀的orm框架,他是怎么设计缓存的呢,没准我们看了之后能够收到一点启发。

mybatis的缓存分为一级和二级,他除了缓存具备的简单读写功能之外,还额外添加了阻塞、清空策略、序列化、日志等功能并让你可以做到任意组合,够豪横吧,那么豪横的能力是怎么做到的呢,我们给他添加功能很简单,但是让我们可以随意组合,好像蛮难的哈,其实我们想一想,在java编程思想当中提到过一个比继承更加推荐的就叫组合,他其实就是不直接继承父类,而是将其引入对象中,这样既可以松耦合而且也能使用父类的功能。知道了这些我们再来看一下mybatis的代码

可以看到这些都是附加的一些功能,我们进去看看他是如何添加功能的。

                               

可以看到,就是我们之前想到的组合,我们将对象传入,并新增一些功能,不就达到了目的吗,而将这个新增之后的作为原始对象,再使用同样的方式去添加新功能,就可以达到任意组合的方式去使用,而这种方式在设计模式中被称为装饰器模式(哈哈,设计模式好像也没那么难)。

说完附加功能和设计模式,我们再看看他的最基本的功能-读写,其实最重要的就是缓存如何命中,可以看到mybatis的缓存命中,最重要的一个点就是cachekey

   

上图是cachekey的四个重要的参数,重写的equals也是相当的复杂,我们明明几个字符串就可以解决的问题,为啥要设计这么复杂?这不是很消耗资源吗,做这些的目的到底是啥呢,我们相信mybatis搞这么复杂绝不是为了装逼。一般来说,map的key为字符串,而mybatis支持动态sql,因此缓存的key不能仅仅通过String来表示,所以使用cachekey来封装多个影响缓存的因素,而判断两个cachekey是否相同关键是比较两个对象的hash值是否一致。每次更新数据同时也会刷新cachekey的值。我们已经知道mybatis是如何命中缓存的,其基本数据结构还是map,其实在我们自己设计缓存的时候,map也完全足够用了,像redis中双端链表,压缩列表,集合,跳表等数据结构,一般来说除了特殊情况,我们确实是不需要用到,所以对于缓存设计,也需要考虑一些其它的因素。

大家可以看下,mybatis的缓存基础数据结构是hashmap,对于一级缓存来说,由于他的作用域是当前会话,因此不会在多线程之间进行操作,不会有线程安全的问题,但是,二级缓存是跨sqlSession的,多线程并发的情况下,hashMap是肯定无法保证线程安全,所以,mybatis在设计的时候,二级缓存会加上一个synchronized装饰器,其实现就是在方法上面加synchronized关键字,他还有其他的一些装饰器比如LRU,FIFO等处理对象达到上限的清除策略,对于缓存的持久化,也是一个比较重要的话题,mybatis不像redis,他是本地缓存,随程序启动而启动,因此,没有做缓存持久化操作,但是,我们在设计缓存的时候,确实也需要考虑到这一点是否需要。

缓存的设计确实学问很大,本人才疏学浅,只能简单聊聊自己对于这方面的理解,看了mybatis的源码,才知道设计模式为啥这么被推崇,希望以后自己能走得更远吧!!!

mybatis缓存源码分析之浅谈缓存设计的更多相关文章

  1. Spring源码分析 之浅谈设计模式

    一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级  零配置, ...

  2. 【JDK源码分析】浅谈HashMap的原理

    这篇文章给出了这样的一道面试题: 在 HashMap 中存放的一系列键值对,其中键为某个我们自定义的类型.放入 HashMap 后,我们在外部把某一个 key 的属性进行更改,然后我们再用这个 key ...

  3. netty源码分析 - Recycler 对象池的设计

    目录 一.为什么需要对象池 二.使用姿势 2.1 同线程创建回收对象 2.2 异线程创建回收对象 三.数据结构 3.1 物理数据结构图 3.2 逻辑数据结构图(重要) 四.源码分析 4.2.同线程获取 ...

  4. Mybatis源码分析之Cache二级缓存原理 (五)

    一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...

  5. mybatis源码分析之06二级缓存

    上一篇整合redis框架作为mybatis的二级缓存, 该篇从源码角度去分析mybatis是如何做到的. 通过上一篇文章知道,整合redis时需要在FemaleMapper.xml中添加如下配置 &l ...

  6. mybatis源码分析之05一级缓存

    首先需要明白,mybatis的一级缓存就是指SqlSession缓存,Map缓存! 通过前面的源码分析知道mybatis框架默认使用的是DefaultSqlSession,它是由DefaultSqlS ...

  7. MyBatis 3源码分析

    Mybatis3.2源码分析: 一.加载配置文件.     使用SAX解析配置文件.读取xml配置文件后,调用XMLConfigBuilder.parse()方法,在parse方法中再调用parseC ...

  8. Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析

    像Mybatis.Hibernate这样的ORM框架,封装了JDBC的大部分操作,极大的简化了我们对数据库的操作. 在实际项目中,我们发现在一个事务中查询同样的语句两次的时候,第二次没有进行数据库查询 ...

  9. 深度 Mybatis 3 源码分析(一)SqlSessionFactoryBuilder源码分析

    MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java ...

随机推荐

  1. UWP 实现Tab导航首页

    先看效果: 这个是用Pivot来实现 1.自定义Pivot的样式,使用Blend工具生成模板,将HeaderTemplate的布局都隐藏 1 <Style x:Key="PivotSt ...

  2. iOS音乐电台类项目开发

    1.技术难度不是太大,代码大致如下 2.用到的一些第三方 ZFProgressView,pageController,RESideMenu,MJRefresh,MBProgressHUD,RNFros ...

  3. 数据库SQL调优的几种方式 EFcore读的情况下使用 AsNoTracking非跟踪查询

    不要用GUID 当主键 没有规律 可以用雪花ID DBA 优化法则 硬件资源是根本,DBA是为了充分利用硬件资源 一般清空下可以不使用外键 可以提高性能 合理使用临时表 临时表分页; 一些查询语句加w ...

  4. C#的TimeSpan

    前言 参考 TimeSpan介绍: https://blog.csdn.net/weixin_41600552/article/details/82220645 微软文档: https://docs. ...

  5. jQuery中live()使用报错,TypeError: $(...).live is not a function

    原博文 https://blog.csdn.net/sdfdyubo/article/details/59536781 使用 原写法 /*为选项卡绑定右键*/ $(".tabs li&quo ...

  6. 谈谈hive中join下on和where

    本文为博客园作者所写: 一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 很多人如果先接触mysql的执行顺序(from ->on ->join -&g ...

  7. SpringBoot入门到精通系列教程 - Filter/WebFilter

    1. Filter简介 1.1. SpringBoot 中Filter的作用 1.2. @WebFilter 2. 基于@WebFilter的实现 2.1. SpringbootApplication ...

  8. 常用的linux指令

    a.cd /home 进入 '/ home' 目录' b.cd .. 返回上一级目录 c.cd ../.. 返回上两级目录 d.mkdir dir1 创建一个叫做 'dir1' 的目录' e.mkdi ...

  9. wildfly 21的配置文件和资源管理

    目录 简介 wildfly的配置文件 extensions profile path interface socket-binding management 资源管理 总结 简介 在上一篇文章我们介绍 ...

  10. JAVA初始化及类的加载

    在许多传统语言中,程序是作为启动过程的一部分被加载的.然后是初始化,紧接着程序开始运行.这些语言的初始化过程必须小心控制,以确保定义为static的东西,其初始化顺序不会造成麻烦.例如C++期望一个s ...