mybatis缓存源码分析之浅谈缓存设计
本文是关于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缓存源码分析之浅谈缓存设计的更多相关文章
- Spring源码分析 之浅谈设计模式
一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级 零配置, ...
- 【JDK源码分析】浅谈HashMap的原理
这篇文章给出了这样的一道面试题: 在 HashMap 中存放的一系列键值对,其中键为某个我们自定义的类型.放入 HashMap 后,我们在外部把某一个 key 的属性进行更改,然后我们再用这个 key ...
- netty源码分析 - Recycler 对象池的设计
目录 一.为什么需要对象池 二.使用姿势 2.1 同线程创建回收对象 2.2 异线程创建回收对象 三.数据结构 3.1 物理数据结构图 3.2 逻辑数据结构图(重要) 四.源码分析 4.2.同线程获取 ...
- Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
- mybatis源码分析之06二级缓存
上一篇整合redis框架作为mybatis的二级缓存, 该篇从源码角度去分析mybatis是如何做到的. 通过上一篇文章知道,整合redis时需要在FemaleMapper.xml中添加如下配置 &l ...
- mybatis源码分析之05一级缓存
首先需要明白,mybatis的一级缓存就是指SqlSession缓存,Map缓存! 通过前面的源码分析知道mybatis框架默认使用的是DefaultSqlSession,它是由DefaultSqlS ...
- MyBatis 3源码分析
Mybatis3.2源码分析: 一.加载配置文件. 使用SAX解析配置文件.读取xml配置文件后,调用XMLConfigBuilder.parse()方法,在parse方法中再调用parseC ...
- Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析
像Mybatis.Hibernate这样的ORM框架,封装了JDBC的大部分操作,极大的简化了我们对数据库的操作. 在实际项目中,我们发现在一个事务中查询同样的语句两次的时候,第二次没有进行数据库查询 ...
- 深度 Mybatis 3 源码分析(一)SqlSessionFactoryBuilder源码分析
MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java ...
随机推荐
- grafana 的主体架构是如何设计的?
grafana 的主体架构是如何设计的? grafana 是非常强大的可视化项目,它最早从 kibana 生成出来,渐渐也已经形成了自己的生态了.研究完 grafana 生态之后,只有一句话:可视化 ...
- Java基础进阶:内部类lambda重点摘要,详细讲解成员内部类,局部内部类,匿名内部类,Lambda表达式,Lambda表达式和匿名内部类的区别,附重难点,代码实现源码,课堂笔记,课后扩展及答案
内部类lambda重点摘要 内部类特点: 内部类可以直接访问外部类,包括私有 外部类访问内部类必须创建对象 创建内部对象格式: 外部类.内部类 对象名=new外部类().new内部类(); 静态内部类 ...
- 将XML转换为实体
需求 将XML文件中的数据经过转换后插入到数据库中. 参考 C#实体类和XML的相互转换 https://blog.csdn.net/pan_junbiao/article/details/82938 ...
- 毕业三年,如何达到月薪30K?我想跟你聊聊!!
写在前面 很多读者私信问我,自己工作三多年了,随着工作年限的不断增长,感觉自己的技术水平与自己的工作年限严重不符.想跳槽出去换个新环境吧,又感觉自己的能力达不到心仪公司的标准,即使投了简历也没人来通知 ...
- [NOIP2013 提高组] 货车运输
前言 使用算法:堆优化 \(prim\) , \(LCA\) . 题意 共有 \(n\) 个点,有 \(m\) 条边来连接这些点,每条边有权值.有 \(q\) 条类似于 \(u\) \(v\) 询问, ...
- 深入浅出!阿里P7架构师带你分析ArrayList集合源码,建议是先收藏再看!
ArrayList简介 ArrayList 是 Java 集合框架中比较常用的数据结构了.ArrayList是可以动态增长和缩减的索引序列,内部封装了一个动态再分配的Object[]数组 这里我们可以 ...
- [leetcode]39combinationsum回溯法找几个数的和为目标值
import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Given a set of can ...
- Javascript 获得数组中相同或不同的数组元素
Javascript 获得数组中相同或不同的数组元素 在Javascript中,偶尔会用到获取数组中相同或不同的元素值的情况,以下提供了获得数组中相同或不同的 元素函数供参考学习使用. // 数字类型 ...
- Java学习日报7.30
package dog;import java.util.*;public class Dog { private String dogName; private String dogColor; p ...
- Spring Boot 2.x基础教程:多个文件的上传
昨天,我们介绍了如何在Spring Boot中实现文件的上传.有读者问:那么如果有多个文件要同时上传呢?这就马上奉上,当碰到多个文件要同时上传的处理方法. 动手试试 本文的动手环节将基于Spring ...