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

发布于:2025-05-12 ⋅ 阅读:(13) ⋅ 点赞:(0)

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。因为可以放在不同的程序甚至服务器当中,所以获取的内存大,但是因为属于不同进程,所以必定会有网络开销,如果放在内网使用的话,这个网络开销还是可以接受的。

网站公告

今日签到

点亮在社区的每一天
去签到