0
点赞
收藏
分享

微信扫一扫

Mybatis之缓存机制

一. 缓存是什么?

一说到缓存,我们可能都会想到Cashe,这里摘自百度百科对它的解释:它原本是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。它的工作原理是当CPU要读取一个数据时,首先从CPU缓存中查找,找到就立即读取并送给CPU处理;没有找到,就从速率相对较慢的内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。

Mybatis之缓存机制_缓存

以上部分内容可能看不懂,没关系,你只需要知道正是由于这样的读取机制,使得CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在CPU缓存中,只有大约10%需要从内存读取。这样大大节省了CPU直接读取内存的时间,非常快捷!!!


简而言之,以cpu中的缓存举例,缓存其实就是数据交换的缓冲区【又称Cashe】,是存贮数据(使用频繁的数据)的临时地方。当用户查询数据,首先在缓存中寻找,如果找到了则直接执行。如果找不到,则去数据库中查找。


二. 为什么要使用缓存?

举个生活中的例子,当我们在线观看视频时,以哔哩哔哩网站为例,你会发现,底下的进度条会实时显示蓝色,白色等两种颜色。不难发现,蓝色代表的是视频实际播放的进度,而白色代表的是视频实时预先缓存的进度。


这种让用户一边下载一边观看、收听,而不要等整个文件下载到自己的计算机上才可以观看的网络传输技术,就是鼎鼎大名的流媒体技术。该技术的原理是先在使用者端的计算机上创建一个缓冲区,在播放前预先下一段数据作为缓冲,在网路实际连线速度小于播放所耗的速度时,播放程序就会取用一小段缓冲区内的数据,这样可以避免播放的中断,也使得播放品质得以保证。该技术在很多音频影视网站上被大量使用,旨在丰富用户的使用体验并提高音频的播放性能。


而程序中的缓存【Mybatis缓存】,亦是如此,Mybatis使用缓存优势可以提高查询效率,并降低服务器的压力。它的本质就是用利用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据,减少数据库IO,减轻服务器压力,减少网络延迟,加快页面打开速度。


三. Mybatis中的缓存分哪几种?

👉分类


1.一级缓存

2.二级缓存

3.第三方缓存


3.1 Mybatis缓存机制之一级缓存

👉概述


一级缓存【本地缓存(Local Cache)或SqlSessiona级别缓存】


🤔什么是SqlSessiona?


SqlSession是一个会话,相当于JDBC中的一个Connection对象,是整个Mybatis运行的核心,它是MyBatis的关键对象,是执行持久化操作的独享,类似于JDBC中的Connection。它是应用程序与持久层之间执行交互操作的一个单线程对象,也是MyBatis的核心接口之一


👉特点


一级缓存默认开启

不能关闭

可以清空

💡 :有点类似于使用腾讯视频网站去看电影,电影观看进度条前的那一小段灰色的进度条


👉缓存原理


第一次获取数据时,先从数据库中加载数据,将数据缓存至Mybatis一级缓存中【缓存底层实现原理Map,key:hashCode+查询的Sqlld+编写的sal查询语句+参数】

以后再次获取数据时,先从一级缓存中获取,如未获取到数据,再从数据库中获取数据

不信?请看如下测试代码的体现

代码示例如下:

     

@Test
public void test04(){
    try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

        //第一次调用selectEmpByOneOpr(1);
        List<Employee> employees = employeeMapper.selectEmpByOneOpr(1);
        System.out.println(employees);

        System.out.println("---------------------------------------------");
        //第二次调用selectEmpByOneOpr(1);
        List<Employee> employees1 = employeeMapper.selectEmpByOneOpr(1);
        System.out.println(employees1);



    } catch (IOException e) {
        e.printStackTrace();
    }
}

举报

相关推荐

0 条评论