初学Mybatis之缓存

news2024/11/13 9:38:14

所有的查询都需要连接数据库,而连接数据库消耗资源

我们可以把一次查询的结果暂时存在一个可以直接获取到的地方(内存:缓存)

我们再次查询相同数据的时候,直接走缓存,不走数据库

缓存:存在内存中的临时数据

将用户经常查询的数据放在缓存(内存)中,

用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,

从缓存中查询,从而提高查询效率,解决高并发系统的性能问题

经常查询且不经常改变的数据可以使用缓存

使用缓存可以减少和数据库的交互次数,减少系统开销,提高系统效率

读写分离,主从复制

Mybatis 系统中默认定义了两级缓存:一级缓存(本地)和二级缓存(全局缓存)

默认情况下,只有一级缓存开启(SqlSession 级别的缓存,也称本地缓存

二级缓存需要手动开启和配置,它是基于 namespace 级别的缓存,一个空间名称对应一个二级缓存

为了提高扩展性,Mybatis 定义了缓存接口 Cache

可以通过实现 Cache 接口来自定义二级缓存


一级缓存:

映射语句文件中的所有 select 语句的结果将会被缓存

写个接口:

    //根据ID查询用户
    User getUserById(@Param("id") int id);

动态 SQL:

    <select id="getUserById" resultType="com.demo.pojo.User">
        select * from user
        <where>
            <if test="id != null">
                id = #{id}
            </if>
        </where>
    </select>

测试:判断两次查询结果是否相同

    //根据id查询
    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.getUserById(1);
        System.out.println(user);

        User user1 = mapper.getUserById(1);
        System.out.println(user1);

        System.out.println(user==user1);

        sqlSession.close();
    }

结果为 true:

 

映射语句文件中的所有 insert、updatedelete 语句会刷新缓存

写个接口:

    //修改数据
    int update(User user);

动态 SQL:

    <update id="update" parameterType="com.demo.pojo.User">
        update user
        <set>
            name = #{name}
        </set>
        <where>
            id = #{id}
        </where>
    </update>

测试:

修改一条数据

    //修改数据
    @Test
    public void update(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.getUserById(2);
        System.out.println(user);

        mapper.update(new User(1,"张三"));

        User user1 = mapper.getUserById(2);
        System.out.println(user1);

        System.out.println(user==user1);

        sqlSession.close();
    }

运行结果为 false:刷新缓存

缓存失效的情况:

1.查询不同

2.增删改操作,可能会改变原来的数据,所以必定刷新缓存

3.查询不同的 Mapper.xml

4.手动清理缓存,sqlSession.clearCache();


二级缓存:

一级缓存默认开启,只在一次 SqlSession 中有效,也就是拿到连接关闭连接这个区间段

默认情况下,只启用了本地的会话缓存(一级),它仅仅对一个会话中的数据进行缓存

要启用全局的二级缓存,只需要在你的 SQL 映射文件(mapper.xml)中添加一行 <cache/>

工作机制:

一个会话查询一条数据,这个数据会被放在当前会话的一级缓存中

当前会话关闭,一级缓存中的数据被保存到二级缓存中

新的会话查询信息,就从二级缓存中获取内容

不同的 mapper 查出的数据会放在自己对应的缓存(map)中

mybatis-config.xml 开启全局缓存:

    <settings>
        <!-- 显示的开启全局缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

在当前 Mapper.xml 中使用二级缓存:

    <!-- 在当前 Mapper.xml 中使用二级缓存 -->
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

可用的清除策略有:

LRU – 最近最少使用:移除最长时间不被使用的对象(默认的清除策略是 LRU)

FIFO – 先进先出:按对象进入缓存的顺序来移除它们

SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象

WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象

flushInterval(刷新间隔)、size(引用数目)、readOnly(只读)

二级缓存是事务性的,当 SqlSession 完成并提交时,或是完成并回滚,

但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新

测试:

    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        SqlSession sqlSession2 = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
        sqlSession.close();


        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        User user2 = mapper2.getUserById(1);
        System.out.println(user2);

        System.out.println(user==user2);

        sqlSession2.close();
    }

结果为 true:

缓存会使用最近最少使用算法(LRU, Least Recently Used)来清除不需要的缓存

缓存不会定时进行刷新(也就是说,没有刷新间隔)

缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用

缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,

可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改

缓存只作用于 cache 标签所在的映射文件中的语句

如果混合使用 Java API 和 XML 映射文件,在共用接口中的语句将不会被默认缓存,

需要使用 @CacheNamespaceRef 注解指定缓存作用域

小结:

1.只要开启了二级缓存,在同一个 Mapper 下就有效

2.所有的数据都会先放在一级缓存中

3.只有当会话提交或者关闭时,才会提交到二级缓存中(类似转存)


Mybatis 缓存原理(顺序):

1.先看二级缓存中有没有

2.再看一级缓存中有没有

3.查询数据库

自定义缓存 EhCache:

EhCache 是一个纯 Java 的进程内缓存框架

pom.xml 导入 mybatis-ehcache 的 jar 包

    <dependency>
      <groupId>org.mybatis.caches</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.2.3</version>
    </dependency>

mapper.xml 使用自定义缓存:

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

resoures 目录下创建 ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">

    <diskStore path="./tmpdir/Tmp_EhCache"/>

    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>

    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
</ehcache>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1960589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.5.1、查找和排序算法-算法介绍

算法特性 算法是对特定问题求解步骤的一种描述&#xff0c;它是指令的有限序列&#xff0c;其中每一条指令表示一个或多个操作。简单的说算法就是某个问题的解题思路&#xff0c;算法的五个重要特性如下&#xff1a; 有穷性。一个算法必须总是&#xff08;对任何合法的输入值…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十二章 设备树常用of函数

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

NAS变身云盘管理大师:群晖部署AList全攻略!

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒🔑 AList功能简介🚀 快速部署📝 操作步骤🐳 Docker容器部署:灵活与强大📝 操作步骤📝 群晖部署🎈 获取方式 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 在这个数字化时代,我们似乎都不可避免地拥有多个…

【数据结构】:大厂面试经典链表OJ题目详解

反转链表 206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 思路解透 本题就是通过不停地将最先的 head 节点位置的后一位插到最前面&#xff0c;完成链表的反转 本题需要两个节点变量 cur&#xff1a;其任务就是定位到原 head 节点位置的前一位&#xff0c;然后将自己…

列表(list)—python

一、列表的定义方式 列表内的每一个数据称为元素&#xff0c;列表以[ ]作为标识&#xff0c;列表内的每个元素之间用逗号隔开。 列表的基本语法如下&#xff1a; #字面量 [元素1,元素2,元素3,元素4,……]#定义变量 变量名称[元素1,元素2,元素3,元素4,……]#定义空列表 变量名…

Linux的防火墙

一、防火墙概述 防火墙是一种计算机硬件和软件的结合&#xff0c;使internet和intranet之间建立一个安全网关&#xff08;Security Gateway&#xff09;&#xff0c;从而保护内网免受非法用户侵入的技术。 防火墙主要由服务访问规则、验证工具、包过滤和应用网关4个部分组成。…

安防视频监控EasyCVR视频汇聚平台无法编辑设备通道信息的原因排查及解决

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…

ECharts - 坐标轴刻度数值处理

写图表时&#xff0c;Y轴的数值过大&#xff0c;不太可能直接展示&#xff0c;这时候就得简写了&#xff0c;或者百分比展示的也要处理&#xff0c;如下图&#xff1a; yAxis: {type: value,// Y轴轴线axisLine: { show: false }, // 刻度线axisTick: { show: false },// 轴刻度…

ECharts实现按月统计和MTBF统计

一、数据准备 下表是小明最近一年的旅游记录 create_datecity_namecost_money2023-10-10 10:10:10北京14992023-11-11 11:11:11上海29992023-12-12 12:12:12上海19992024-01-24 12:12:12北京1232024-01-24 12:12:12上海2232024-02-24 12:12:12广州5642024-02-24 12:12:12北京…

学习笔记之Java篇(0729)

p 数组 大纲知识点数组的概念数组的定义、四个特点数组的常见操作普通遍历、for-each遍历、java.util.Array类用法多维数组多维数组的内存结构、存储表格、Javabean和数组存储表格常见算法冒泡排序基础算法、冒泡排序优化算法、二分法查找&#xff08;折半查找&#xff09; 1、…

【JavaWeb】Filter

基本使用 使用了过滤器之后&#xff0c;要想访问web服务器上的资源&#xff0c;必须先经过滤器&#xff0c;过滤器处理完毕之后&#xff0c;才可以访问对应的资源。过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;登录校验、统一编码处理、敏感字符处理等。 使用操…

nginx 子路径映射配置

如果子路径转发到另一个服务器IP&#xff0c;配置如下&#xff0c;注意都要以“/”结尾。 #指定nginx进程数 worker_processes 1; pcre_jit on;events {# 连接数上限worker_connections 30000; }#http服务 http {server {listen 20012;# 监听的端口号server_name localho…

Spring IoC DI(笔记)

一.了解SpringIoC&DI 1.1IoC 通过前面的学习,我们知道了Spring是一个开源框架,他让我们的开发更加简单.他支持广泛的应用场 景,有着活跃而庞大的社区,这也是Spring能够长久不衰的原因&#xff0c;但是这个概念相对来说,还是比较抽象&#xff0c;我们用一句更具体的话来概…

纯原创【车牌识别】基于图像处理的车牌识别——matlab项目实战(含GUI界面)详解

摘要 车牌识别系统乃计算机视觉与模式识别技术于智能交通领域的重要研究课题之一。其作用在于从复杂背景里提取运动中的汽车牌照&#xff0c;进而识别出车牌号码。车牌识别技术在高速公路电子收费、日常停车场管理以及交通违章监控等场景得到广泛运用。它的问世对于维护交通安全…

代码随想录二刷(链表章节)

代码随想录二刷(链表章节) 链表就是通过指针串联在一起的线性结构&#xff0c;每个节点都是由一个数据域和指针域(存放下一个节点的指针)。 双链表就是每个节点中既有指向前一个节点的&#xff0c;也有指向后一个节点的。 循环链表就是把头和尾连起来。 性能分析如下&#xf…

Java面试八股之@Autowired 和 @Resource的区别

Autowired 和 Resource的区别 在Spring框架中&#xff0c;Autowired 和 Resource 是两个常用的依赖注入注解&#xff0c;但它们有一些关键的区别。下面是这两个注解的主要差异&#xff1a; 1. 注解来源 Autowired&#xff1a; 是Spring框架提供的注解&#xff0c;位于包 or…

TerraSAR-XTanDEM-X卫星详解(一)

全球SAR卫星大盘点与回波数据处理专栏目录 1. TerraSAR-X简介 TerraSAR-X(Terra Synthetic Aperture Radar-X)和TanDEM-X(TerraSAR-X add-on for Digital Elevation Measurement)是由德国宇航中心(DLR)和EADS Astrium公司共同推出的一对双子卫星。Terra源自拉丁语,是地…

解决win10蓝屏“选择一个选项”的问题!

今天台式机开机&#xff0c;出现蓝屏问题&#xff0c;记录一下。 一、问题 启动修复不行&#xff0c;系统还原没还原点&#xff0c;系统映像恢复没有文件。难道要重装系统&#xff1f;手上只能Win7和XP的启动盘。此路不通。 二、解决 使用命令提示符。输入&#xff1a; bcdb…

《花100块做个摸鱼小网站! · 序》灵感来源

序 大家好呀&#xff0c;我是summo&#xff0c;这次来写写我在上班空闲(摸鱼)的时候做的一个小网站的事。去年阿里云不是推出了个活动嘛&#xff0c;2核2G的云服务器一年只要99块钱&#xff0c;懂行的人应该知道这个价格在业界已经是非常良心了&#xff0c;虽然优惠只有一年&a…

PMP考试难吗?好不好学?

PMP 并不难&#xff0c;虽然新考纲大家都说开盲盒&#xff0c;做阅读理解&#xff0c;但线上考试成绩出的快&#xff0c;晒 3A 的也不少。给大家分享下我的备考经历&#xff0c;希望能给后面备考的同学一点参考吧。 现在的新考纲是要学习三本书的&#xff0c;《PMBOK》第六版、…