当前位置: 首页 > news >正文

MyBatis源码解读5(3.1、缓存简介)

3.1、简介

​ 我们需要记住一句话,程序与数据库之间的交互是性能瓶颈的关键,所以我们在做优化的时候,数据库的优化要做,但是优先级是最低的,比它优先级高的是方面是程序与数据库之间的交互,先从宏观上解决问题,进而再去解决更加微观的问题,主要可以从以下几个点去考虑:

  1. 网络通信(数据传输)
  2. 数据存储的位置(硬盘存储的大量的数据是不利于查询的)
  3. Java对象的复用问题(Connection、Statement对象)

​ 介于以上问题,所以就有了缓存层,缓存是什么?缓存就是我们的内存。 加入了缓存以后,以后Java程序想要访问数据库的时候,首先访问到的不是数据库,而是我们的缓存,缓存里面如果没有Java程序所需要的数据的时候,那么会由缓存去链接到我们的数据库,由缓存来完成数据库的数据查询,在缓存从数据库中查询到数据库的时候,也会首先先将此次查询的结果放到缓存中,进而由缓存返回给Java程序,那么此后如果Java程序第二次去查询同样的数据的时候,就无需再去查询数据库,直接可以由缓存层返回,所以我们可以知道,缓存的存在不是用于第一次返回数据,而是用于第二次甚至以后更多次的返回数据。缓存最大的价值是在程序和数据库之间搭建了一座桥梁,能够把数据都存储在内存中,提高用户的查询效率,尽量避免数据库的硬盘查询。

​ 此时有一个重要的概念:换出。比如说内存中最多只可以存放100个对象,那么此时再有一个对象需要进入到内存中的时候就需要将这100个对象选择一个对象踢出内存,这样新的对象才可以进入到内存,这个过程就是换出的过程。当缓存的区域不够用的时候,我们此时需要将缓存拿出一点出来临时放到硬盘当中,换出的方式就是序列化机制

​ 那么如果要能够实现序列化机制的话(以Java为例),要保证我们的实体对象要实现Serializable接口,所以这也就是我们在写实体类的代码的时候都要实现Serializable接口。那么此时有人可以要来问了,我们不是还可以使用JSON,将对象存储为JSON串存储吗?从结果来看,我们可以知道JSON存储的结果一定是不好的,为什么呢?因为我们知道传统的序列化方式都是以二进制的方式来存储的,但是JSON是以字符串的方式来存储的,同样存储相同量级的数据的时候,二进制的存储方式一定是比字符串更省地方的,也是更快的。那么此时有人来问了,字符串在电脑中最终不是也是以二进制的方式来存储吗?这个毋庸置疑确实,但是字符串的二进制的体量一定是比纯的二进制存储的体量是要大的

​ 那么换出的算法有哪些呢?换出算法指的是当硬盘中内存不够的时候,谁将出局,空出容量给新的对象进来,常见的换出算法有两种:

  1. 最近最久未使用页面置换算法LRU:是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰。
  2. FIFO:FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

​ 了解了缓存相关的知识了以后,那么我们需要思考一个问题,如何将缓存和Java程序相结合的?也就是说如何保证Java程序首先去访问缓存,缓存中没有的时候再去访问数据库,然后数据库将查询到的数据存到缓存中,那么下次再次去查询的时候就不会去查询数据库了,直接去缓存中拿到数据返回,这个操作是是如何确保的呢?要实现这个就是要先了解缓存的分类:

  1. ORM缓存框架自己集成的缓存,一般来说常见的ORM框架,像MyBatis、Hibernate等都会集成缓存,因为在Java代码的三层架构(Controller-Service-Dao)中,只有Dao这一层做链接数据库方面的事情,自然而然在Dao这一次集成缓存是最合适的。优点是操作缓存快,但是获取的内存有限。
  2. 第三方的中间件来充当缓存,这种缓存就是从Java角度出发了,我们可以在Java程序和数据库的中间插入一个新的缓存层,作为内存型数据库,常见的代表是Redis、Memcache。因为可以放在不同的程序甚至服务器当中,所以获取的内存大,但是因为属于不同进程,所以必定会有网络开销,如果放在内网使用的话,这个网络开销还是可以接受的。
http://www.xdnf.cn/news/386785.html

相关文章:

  • 常见的排序算法(Java版)简单易懂好上手!!
  • path环境变量满了如何处理,分割 PATH 到 Path1 和 Path2
  • Java高频面试之并发编程-15
  • ES常识5:主分词器、子字段分词器
  • 嵌入式硬件篇---CAN
  • 【Mac 从 0 到 1 保姆级配置教程 12】- 安装配置万能的编辑器 VSCode 以及常用插件
  • Spring框架(2)---AOP
  • 鱼眼相机生成-BEV鸟瞰图-入门教程
  • Nginx yum 安装
  • 从数据处理到模型训练:深度解析 Python 中的数据结构与操作实践
  • Unity3D仿星露谷物语开发42之粒子系统
  • 使用FastAPI和React以及MongoDB构建全栈Web应用05 FastAPI快速入门
  • Problem C: 异常1
  • 在Java项目中实现本地语音识别与热点检测,并集成阿里云智能语音服务(优化版)
  • 基于Qt的app开发第七天
  • leetcode 454. 4Sum II
  • 【数据库知识】Mysql进阶-高可用MHA(Master High Availability)方案
  • Git标签
  • 多模态大语言模型arxiv论文略读(六十八)
  • 各类有关NBA数据统计数据集大合集
  • Hibernate 性能优化:告别慢查询,提升数据库访问性能
  • 《Effective Python》第1章 Pythonic 思维详解——item03-05
  • C# 高效处理海量数据:解决嵌套并行的性能陷阱
  • 深入理解 JavaScript 中的 FileReader API:从理论到实践
  • React 从零到一执行原理 (2025 最新版)
  • 23、DeepSeek-V2论文笔记
  • 嵌入式硬件篇---IIC
  • 牛客周赛 Round 92 题解 Java
  • 力扣2680题解
  • D. Explorer Space(dfs+剪枝)