spring cache(二)集成

news2024/10/6 7:00:15

一、集成方法

1、pom添加依赖
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--spring cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
2、配置redis连接

配置文件加上:

#redis
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.password=
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.time-between-eviction-runs=30s
3、配置cache

(1)配置文件指定cache类型

#cache
#类型指定redis
spring.cache.type=redis
#一个小时,以毫秒为单位
spring.cache.redis.time-to-live=3600000
#给缓存的建都起一个前缀。  如果指定了前缀就用我们指定的,如果没有就默认使用缓存的名字作为前缀,一般不指定
#spring.cache.redis.key-prefix=CACHE_
#指定是否使用前缀
spring.cache.redis.use-key-prefix=true
#是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true

(2)配置开启cache

import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
@EnableConfigurationProperties(RedisProperties.class)//开启属性绑定配置的功能
public class MyCacheConfig {
}
4、使用

一般在mapper层使用。

类头加@CacheConfig注解,指明cacheNames;

方法上加@Cacheable、@CacheEvict注解直接使用。

4.1、查询

(1)无参

 可以使用方法名作为key

@Cacheable(key = "#root.methodName")
    public List<ParamDTO> listParams() {
        LambdaQueryWrapper<ParamDTO> queryWrapper = new LambdaQueryWrapper<>();
        return paramMapper.selectList(queryWrapper);
    }

(2) 单参(非数组)查询

@Cacheable(key = "{#p0}")
    public List<ParamDTO> listParamsByKey(String key) {
        LambdaQueryWrapper<ParamDTO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParamDTO::getParamKey,key);
        return paramMapper.selectList(queryWrapper);
    }

    @CacheEvict(key = "{#p0}")
    public void deleteByKey(String key) {
        LambdaQueryWrapper<ParamDTO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParamDTO::getParamKey,key);
        paramMapper.delete(queryWrapper);
    }

(3)不建议使用缓存的场景:

范围查询请勿添加缓存,如入参含有数组,Set,List

// Do not add cache
public List<UserPresence> getByUserIds(List<String> userIds) {
  return userStatusMapper.selectBatchIds(userIds);
}

关联查询请勿添加缓存,即当前的返回结果由多个表联合查询得出;

分页查询请勿添加缓存;

基于动态组合的条件查询请勿添加缓存,如入参是Map,其value的值存在性是可变的,常见于前端多选条件查询。

4.2、增删改

假设我之前查询已经缓存了UserDTO的两个key,一个key是id,一个key是accountId+Id。关于这两个key的增删改需要删除缓存。

(1)参数为单个对象(可以有多个参数)且包含所有key的所有字段值:

可以直接取出对应的值来对所有的key进行缓存清除。

如这里入参包含了这两个Key的所有字段(id、accountId),所以直接取出来删除:

@Caching(evict = {
            @CacheEvict(key = "{#p0.id}"),
            @CacheEvict(key = "{#p0.accountId, #p0.id}")
})
public void insert(UserDTO userDTO)

(2)参数含有List对象且包含所有key的所有字段值:

Spring Cache默认只支持String类参数作为cache key,对于Collection类型的参数,无法直接将其作为cache key,此类情况需要通过构造自定义的key解析规则来实现,我们将key拼装后的结果通过包装为一个自定义的CollectionWrapper对象来作为cache key进行解析,此例中调用了del.batchKeys(Collection<String>, Collection<String>)以及del.batchKeys(Collection<String>)方法,其返回结果将会是一个CollectionWrapper对象(里面存放了批量的key1和key2,实际上是通过重写RedisCache的evict()方法进行cache key的判断,如果cache key是CollectionWrapper类型对象,将会走自定义的逻辑)。

@Caching(evict = {
        @CacheEvict(key = "@delKey.batchKeys(#p0?.![#this.accountId], #p0?.![#this.id])"),
        @CacheEvict(key = "@delKey.batchKeys(#p0?.![#this.id])")
})
public void insert(List<UserDTO> users)

(3)参数为单个对象(可以有多个参数)且不包含所有key的所有字段值 

      不建议这样做,应当在入参中包含key所需要的所有字段值。如入参只有id或者accountId,这样对应不上缓存。

(4)参数含有List对象且不包含所有key的所有字段值

不建议这样做,应当在入参中包含key所需要的所有字段值。

5、缓存一致问题

为了避免多线程缓存一致性问题,beforeInvocation还是默认为false。

为了保证缓存正常被删除,处理方式:
方式1: 要求上层传递参数中包含全字段的entity list。
方式2: 或者在repository中增加一个公共的方法deleteList,这个方法里传参是List<Entity>, 由这个方法统一进行缓存的清理,注意: 同repository其他方法先查到list,然后再调用这个统一删除方法,调用时候要保证aop生效(public 方法,注入自身)

二、demo

1、pom

2、配置文件

3、config

4、controller

5、service

6、dao

7、dto

8、测试:

8.1、缓存与删除缓存:

(1)第一次访问localhost:1111/plusDemo/param/listParams控制台输出:

2024-04-25T17:14:33.330+08:00  INFO 36136 --- [nio-1111-exec-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
JDBC Connection [HikariProxyConnection@644769222 wrapping com.mysql.cj.jdbc.ConnectionImpl@5ee5b9f5] will not be managed by Spring
==>  Preparing: SELECT id,param_key,param_value FROM t_param
==> Parameters: 
<==    Columns: id, param_key, param_value
<==        Row: 1, a, a_1
<==        Row: 2, a, a_2
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14369ce6]

再次访问,返回数据和第一次一样,但是控制台无输出,断点可以看到在serveimImpl直接返回了,并没有进入ParamRepository。

(2)删除缓存

多次访问localhost:1111/plusDemo/param/listParamsByKey?key=a后,访问localhost:1111/plusDemo/param/deleteById?key=a,这时再访问listParamsByKey发现又走db层了

==>  Preparing: DELETE FROM t_param WHERE (param_key = ?)
==> Parameters: a(String)
<==    Updates: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@341e0500]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@287ed822] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@222873874 wrapping com.mysql.cj.jdbc.ConnectionImpl@4cad2112] will not be managed by Spring
==>  Preparing: SELECT id,param_key,param_value FROM t_param WHERE (param_key = ?)
==> Parameters: a(String)
<==      Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@287ed822]

8.2、删除缓存加入异常

 @CacheEvict(key = "{#p0}",beforeInvocation = true)
    public void deleteByKey(String key) {
        LambdaQueryWrapper<ParamDTO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ParamDTO::getParamKey,key);
        paramMapper.delete(queryWrapper);
        int a = 1/0;
    }

访问localhost:1111/plusDemo/param/listParamsByKey?key=a后再访问localhost:1111/plusDemo/param/listParamsByKey?key=a可以看到缓存已经清除了,重新走db查询

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

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

相关文章

盲人乘坐公共交通的新篇章:科技赋能,独立出行不再是梦

在我们日常生活中&#xff0c;盲人乘坐公共交通这一话题一直牵动着社会大众的心。近日&#xff0c;一位盲人朋友成功地独自完成了一次公交之旅&#xff0c;他的顺利出行背后&#xff0c;离不开一款名叫蝙蝠避障具有实时避障与拍照识别功能的辅助应用的鼎力支持。 清晨的…

DC-DC电源芯片规格书上的各种参数详解

1.输出电压精确度 输出电压的精确度,也被称为设定点精度,它描述了输出电压的允许误差。该参数通常是在常温,满载和额定输入电压的条件下测得的,它是这样定义的: 输出电压之所以产生误差,是因为元器件本身存在误差,特别是输出端的分压电阻,它将输出电压降低后比PWM比较…

C语言学习/复习34--内存相关笔试题/C与C++的内存/柔性数组

一、动态内存管理笔试题 1.值传递 注意事项1&#xff1a;指针的地址传递需要将指针的地址用二级指针接收&#xff0c;本题属于值传递不属于地址传递 修改&#xff1a;1改为地址传递&#xff0c;2释放malloc()函数申请的空间 注意事项2&#xff1a;printf()字符串时&#xff0c;…

【Pytorch】(十四)C++ 加载TorchScript 模型

文章目录 &#xff08;十四&#xff09;C 加载TorchScript 模型Step 1: 将PyTorch模型转换为TorchScriptStep 2: 将TorchScript序列化为文件Step 3: C程序中加载TorchScript模型Step 4: C程序中运行TorchScript模型 【Pytorch】&#xff08;十三&#xff09;PyTorch模型部署: T…

德思特车载天线方案:打造智能互联的公共安全交通网络

作者介绍 一、方案介绍 随着自动驾驶与智慧汽车概念的逐步推进&#xff0c;人们对汽车的交互性、智能性、互联性有了更高的要求。今天&#xff0c;大多数汽车制造商和供应商普遍将GNSS定位功能与其他信号如广播、电视、蓝牙、Wifi一起集成到汽车中&#xff0c;包括博世、大陆、…

MYSQL学习——存储引擎

mysql体系结构 连接层 连接授权、安全管理服务层 完成缓存的查询、函数执行、语句优化索引层 数据的存储和提取&#xff0c;不同的存储引擎有不同的功能储存层 将数据存储在文件系统上 存储引擎是存储数据、建立索引、更新查询的等技术实现的方式&#xff0c;存储引擎基于表的…

ERP外网访问、快解析助力企业远程办公

ERP系统是现代信息技术和先进管理经验的有效结合&#xff0c;实现对企业经营活动的自动、完整的记录&#xff0c;替代重复劳动&#xff0c;对企业人力资源、物流、资金流、票据流和信息流等的科学管理&#xff0c;实现业务管理数据和财务数据高度统一&#xff0c;实现对企业业务…

【高校科研前沿】东北地理所在遥感领域顶刊RSE发布中国主要红树植物群落遥感分类成果

目录 01 文章简介 02 研究内容 03 文章引用 01 文章简介 论文名称&#xff1a;Mangrove species mapping in coastal China using synthesized Sentinel-2 high-separability images&#xff08;基于Sentinel-2高分离度图像的中国沿海红树群落制图&#xff09; 第一作者及…

名家采访:国家级中国茶文化首席非遗传承人——罗大友

“崇高的理想是一个人心中的太阳,能照亮生活中的每一步。”罗大友&#xff0c;性别&#xff1a;男&#xff0c;国家级中国茶文化首席非遗传承人•中国茶文化研究院院长、美国巴拿马太平洋万国博览会终身评委兼中国区联合主席&#xff0c;大学文化&#xff0c;高级政工师。 “第…

NLP Step by Step -- How to use pipeline

正如我们在摸鱼有一手&#xff1a;NLP step by step -- 了解Transformer中看到的那样&#xff0c;Transformers模型通常非常大。对于数以百万计到数千万计数十亿的参数&#xff0c;训练和部署这些模型是一项复杂的任务。此外&#xff0c;由于几乎每天都在发布新模型&#xff0c…

飞行机器人专栏(十五)-- Kinect DK 多机联合标定

飞行机器人专栏&#xff08;十四&#xff09;-- Kinect DK 人体骨骼点运动提取方法_kinect怎么捕捉骨骼-CSDN博客文章浏览阅读971次&#xff0c;点赞24次&#xff0c;收藏17次。Azure Kinect DK 是一款开发人员工具包&#xff0c;配有先进的 AI 传感器&#xff0c;提供复杂的计…

【EI会议|稳定检索】2024年航空航天、空气动力学与自动化工程国际会议(ICAAAE 2024)

2024 International Conference on Aerospace, Aerodynamics, and Automation Engineering 一、大会信息 会议名称&#xff1a;2024年航空航天、空气动力学与自动化工程国际会议 会议简称&#xff1a;ICAAAE 2024 收录检索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Schol…

安装WSL2

PS C:\Users\pc> wsl --set-default-version 2 有关与 WSL 2 关键区别的信息&#xff0c;请访问 https://aka.ms/wsl2操作成功完成。PS C:\Users\pc> wsl --update 正在检查更新。 已安装最新版本的适用于 Linux 的 Windows 子系统。PS C:\Users\pc> wsl --shutdownPS…

CMake+qt+Visual Studio

#使用qt Creator 创建Cmake 项目,使用Cmake Gui 生成sln 工程&#xff0c;使用Visual Studio 开发 ##使用qt Creator 创建CMake项目 和创建pro工程的步骤一致&#xff0c;只是在选择构建系统的步骤上选择CMake,接下来步骤完全相同 工程新建完成之后&#xff0c;构建cmake 项…

小程序AI智能名片S2B2C商城系统:四大主流商业模式深度解析与实战案例分享

在私域电商迅速崛起的大背景下&#xff0c;小程序AI智能名片S2B2C商城系统以其独特的商业模式和强大的功能&#xff0c;正成为品牌商们争相探索的新领域。在这一系统中&#xff0c;拼团模式、会员电商、社区团购和KOC营销等四种主流模式&#xff0c;为品牌商提供了多样化的营销…

AI-数学-高中-45函数单调性与导数

原作者视频&#xff1a;【导数】【一数辞典】5函数单调性与导数&#xff08;重要&#xff09;_哔哩哔哩_bilibili 导数最重要作用&#xff1a;判断函数单调性。 示例&#xff1a;

跟着Datawhale重学数据结构与算法(3)---排序算法

开源链接&#xff1a;【 教程地址 】【电子网站】 【写博客的目的是记录自己学习过程&#xff0c;方便自己复盘&#xff0c;专业课复习】 数组排序&#xff1a; #mermaid-svg-F3iLcKsVv8gcmqqC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16p…

微信小程序-------模板与配置

能够使用 WXML 模板语法渲染页面结构能够使用 WXSS 样式美化页面结构能够使用 app.json 对小程序进行全局性配置能够使用 page.json 对小程序页面进行个性化配置能够知道如何发起网络数据请求 一.WXML 模板语法 数据绑定 1. 数据绑定的基本原则 ① 在 data 中定义数据 ② 在…

软考 系统架构设计师系列知识点之软件可靠性基础知识(5)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之软件可靠性基础知识&#xff08;4&#xff09; 所属章节&#xff1a; 第9章. 软件可靠性基础知识 第1节 软件可靠性基本概念 9.1.3 可靠性目标 前文定量分析软件的可靠性时&#xff0c;使用失效强度来表示软件缺陷对…

C/C++开发,opencv-ml库学习,随机森林(RTrees)应用

目录 一、随机森林算法 1.1 算法简介 1.2 OpenCV-随机森林&#xff08;Random Forest&#xff09; 二、cv::ml::RTrees应用 2.2 RTrees应用 2.2 程序编译 2.3 main.cpp全代码 一、随机森林算法 1.1 算法简介 随机森林算法是一种集成学习&#xff08;Ensemble Learning&a…