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

redis spring cache

数据库的数据是存储在硬盘上的,频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中,可以大大减轻数据库的访问压力。
SpringCache

SpringCache提供基本的Cache抽象,并没有具体的缓存能力,需要配合具体的缓存实现来完成,目前SpringCache支持redis、ehcache、simple(基于内存)等方式来实现缓存。

org.springframework.boot spring-boot-starter-cache
1
2
3
4

Spring常用的缓存注解

非常好的参考文章
SpringBoot基础系列-SpringCache使用
spring boot2 (28)-cache缓存
SpringBoot2.x—SpringCache(2)使用
通过继承CachingConfigurerSupport类自定义缓存管理器【与本文方式不同,值得一看】

@EnableCaching:开启缓存功能,一般使用在springboot的启动类或配置类上
@Cacheable:使用缓存。在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;没有则调用方法并将方法返回值放进缓存。

@Cacheable属性名 用途 备注
cacheNames 指定缓存空间的名称,不同缓存空间的数据是彼此隔离的
key 同一个cacheNames中通过key区别不同的缓存。如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,如:@CachePut(value = “demo”, key = “‘user’+#user.id”),字符串中spring表达式意外的字符串部分需要用单引号 SpringCache提供了与缓存相关的专用元数据,如target、methodMame、result、方法参数等,如:@CachePut(value = “demo”, key = “#result==null”)
keyGenrator key的生成策略,SpringCache默认使用SimpleKeyGenerator,默认情况下将参数值作为键,但是可能会导致key重复出现,因此一般需要自定义key的生成策略
condition condition是在调用方法之前判断条件,满足条件才缓存 @Cacheable(cacheNames=“book”, condition=“#name.length() < 32”)
unless unless是在调用方法之后判断条件,如果SpEL条件成立,则不缓存【条件满足不缓存】 @Cacheable(cacheNames = “hello”,unless=“#result.id.contains(‘1’)” )
sync 缓存过期之后,如果多个线程同时请求对某个数据的访问,会同时去到数据库,导致数据库瞬间负荷增高。Spring4.3为@Cacheable注解提供了一个新的参数“sync”(boolean类型,默认为false)。当设置它为true时,只有一个线程的请求会去到数据库,其他线程都会等待直到缓存可用。这个设置可以减少对数据库的瞬间并发访问。

@CachePut:更新缓存,将方法的返回值放到缓存中

//当返回值为null时,通过unless属性
@CachePut(key = “#id”, unless=”#result == null”)

1
2@CacheEvict:清空缓存
@Caching:组合定义多种缓存功能
@CacheConfig:用于标注在类上,可以存放该类中所有缓存的公有属性,比如设置缓存空间的名字cacheNames、key生成策略keyGenerator、缓存管理器cacheManager

SpringCache采用Redis实现缓存

依赖
org.springframework.boot spring-boot-starter-cache 2.3.0.RELEASE org.springframework.boot spring-boot-starter-data-redis 2.3.0.RELEASE lettuce-core io.lettuce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21配置yaml文件

spring:
redis:
database: 0
host: www.onething.top
port: 6379
password: 123456nw
#配置jedis客户端,这里也可以jedis替换为lettuce客户端,下级配置都一样
jedis:
pool:
# 连接池中的最大空闲连接 默认8
max-idle: 8
# 连接池中的最小空闲连接 默认0
min-idle: 0
# 连接池最大连接数 默认8 ,负数表示没有限制
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认-1
max-wait: -1
timeout: 3000
cache:
type: redis # 指定使用的缓存类型

redis: 当自定义ChacheManager时,就这里的配置不需要配置,配置了也不起作用

use-key-prefix: true

key-prefix: “demo:”

time-to-live: 60000 #缓存超时时间 单位:ms

cache-null-values: false #是否缓存空值

cache-names: user

cache:
ttl: ‘{“user”:60,“dept”:30}’ #自定义某些缓存空间的过期时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28自定义ChacheManager、缓存key的生成策略,将默认的jdk序列化策略修改为json序列化策略

@Configuration
public class RedisConfiguration {

// ${cache} 获取配置文件的配置信息   #{}是spring表达式,获取Bean对象的属性
@Value("#{${cache}}")
private Map<String, Long> ttlParams;/*** @param redisConnectionFactory* @功能描述 redis作为缓存时配置缓存管理器CacheManager,主要配置序列化方式、自定义* <p>* 注意:配置缓存管理器CacheManager有两种方式:* 方式1:通过RedisCacheConfiguration.defaultCacheConfig()获取到默认的RedisCacheConfiguration对象,* 修改RedisCacheConfiguration对象的序列化方式等参数【这里就采用的这种方式】* 方式2:通过继承CachingConfigurerSupport类自定义缓存管理器,覆写各方法,参考:* https://blog.csdn.net/echizao1839/article/details/102660649* <p>* 切记:在缓存配置类中配置以后,yaml配置文件中关于缓存的redis配置就不会生效,如果需要相关配置需要通过@value去读取*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();redisCacheConfiguration = redisCacheConfiguration// 设置key采用String的序列化方式.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer.UTF_8))//设置value序列化方式采用jackson方式序列化.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))//当value为null时不进行缓存.disableCachingNullValues()// 配置缓存空间名称的前缀.prefixCacheNameWith("demo:")//全局配置缓存过期时间【可以不配置】.entryTtl(Duration.ofMinutes(30L));//专门指定某些缓存空间的配置,如果过期时间【主要这里的key为缓存空间名称】Map<String, RedisCacheConfiguration> map = new HashMap<>();Set<Map.Entry<String, Long>> entries = ttlParams.entrySet();for (Map.Entry<String, Long> entry : entries) {//指定特定缓存空间对应的过期时间map.put("user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(40)));map.put(entry.getKey(), redisCacheConfiguration.entryTtl(Duration.ofSeconds(entry.getValue())));}return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration)  //默认配置.withInitialCacheConfigurations(map)  //某些缓存空间的特定配置.build();
}/*** 自定义缓存的redis的KeyGenerator【key生成策略】* 注意: 该方法只是声明了key的生成策略,需在@Cacheable注解中通过keyGenerator属性指定具体的key生成策略* 可以根据业务情况,配置多个生成策略* 如: @Cacheable(value = "key", keyGenerator = "cacheKeyGenerator")*/
@Bean
public KeyGenerator keyGenerator() {/*** target: 类* method: 方法* params: 方法参数*/return (target, method, params) -> {//获取代理对象的最终目标对象StringBuilder sb = new StringBuilder();sb.append(target.getClass().getSimpleName()).append(":");sb.append(method.getName()).append(":");//调用SimpleKey的key生成器Object key = SimpleKeyGenerator.generateKey(params);return sb.append(key);};
}/*** @param redisConnectionFactory:配置不同的客户端,这里注入的redis连接工厂不同: JedisConnectionFactory、LettuceConnectionFactory* @功能描述 :配置Redis序列化,原因如下:* (1) StringRedisTemplate的序列化方式为字符串序列化,* RedisTemplate的序列化方式默为jdk序列化(实现Serializable接口)* (2) RedisTemplate的jdk序列化方式在Redis的客户端中为乱码,不方便查看,* 因此一般修改RedisTemplate的序列化为方式为JSON方式【建议使用GenericJackson2JsonRedisSerializer】*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = serializer();RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// key采用String的序列化方式redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);// value序列化方式采用jacksonredisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);// hash的key也采用String的序列化方式redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8);//hash的value序列化方式采用jacksonredisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setConnectionFactory(redisConnectionFactory);return redisTemplate;
}/*** 此方法不能用@Ben注解,避免替换Spring容器中的同类型对象*/
public GenericJackson2JsonRedisSerializer serializer() {return new GenericJackson2JsonRedisSerializer();
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105应用

(1)开启缓存功能

@EnableCaching //开启缓存的主键
@SpringBootApplication
public class RedisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RedisDemoApplication.class, args);
}
}

1
2
3
4
5
6
7

(2)使用缓存

@Service
@CacheConfig(cacheNames = “user”,keyGenerator = “keyGenerator”)
public class RedisServiceImpl implements RedisService {

@Cacheable(value = "user", key = "'list'")
@Override
public List<User> list() {System.out.println("=========list");User user1 = new User();user1.setId(1);user1.setName("老大");User user2 = new User();user2.setId(2);user2.setName("老二");List<User> users = new ArrayList<>();users.add(user1);users.add(user2);return users;
}@CacheEvict(value = "user", key = "'list'")
@Override
public void del(Integer id) {System.out.println("************************************+id");List<User> users = new ArrayList<>();Iterator<User> iterator = users.iterator();while (iterator.hasNext()) {User user = iterator.next();if (user.getId().equals(id)) {iterator.remove();break;}}
}@CachePut(value = "demo", key = "#result==null")
@Override
public User select(Integer id) {System.out.println("===============dddd================");if (id == 0) {return null;}User user = new User();user.setId(100);user.setName("测试");return user;
}

}
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/user2025/article/details/106595257

https://blog.csdn.net/user2025/article/details/106595257?spm=1001.2101.3001.6650.16&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-16-106595257-blog-135942825.235%5Ev43%5Econtrol&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7ERate-16-106595257-blog-135942825.235%5Ev43%5Econtrol&utm_relevant_index=17

相关文章:

redis spring cache

数据库的数据是存储在硬盘上的&#xff0c;频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中&#xff0c;可以大大减轻数据库的访问压力。 SpringCache SpringCache提供基本的Cache抽象&#xff0c;并没有具体的缓存能力&#xff0c;需要配合具体的缓存实现…...

图解I/O中的零拷贝技术

什么是零拷贝&#xff1f; 零拷贝是一种计算机系统中的 I/O 优化技术&#xff0c;它的核心思想是在数据传输过程中尽可能地减少或完全避免 CPU 将数据从一个存储区域复制到另一个存储区域的操作&#xff0c;从而减少了上下文切换和 CPU 拷贝时间&#xff0c;提高了系统的性能和…...

【设计模式】Java 设计模式之桥接模式(Bridge)

桥接模式&#xff08;Bridge Pattern&#xff09;是结构型设计模式的一种&#xff0c;它主要解决的是抽象部分与实现部分的解耦问题&#xff0c;使得两者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;因为该模式涉及如何组合接口和它们的实现。将抽象部分与实现…...

记录dockers中Ubuntu安装python3.11

参考&#xff1a; docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客...

【算法专题--双指针算法】leetcode--283. 移动零、leetcode--1089. 复写零

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1. 移动零&#xff0…...

【JavaEE -- 多线程3 - 多线程案例】

多线程案例 1.单例模式1.1 饿汉模式的实现方法1.2 懒汉模式的实现方法 2. 阻塞队列2.1 引入生产消费者模型的意义&#xff1a;2.2 阻塞队列put方法和take方法2.3 实现阻塞队列--重点 3.定时器3.1 定时器的使用3.2 实现定时器 4 线程池4.1 线程池的使用4.2 实现一个简单的线程池…...

k8s的pod服务升级,通过部署helm升级

要通过Helm升级Kubernetes&#xff08;k8s&#xff09;中的Pod服务&#xff0c;你可以按照以下步骤进行操作&#xff1a; 安装Helm&#xff1a; 如果你还没有安装Helm&#xff0c;可以通过官方文档提供的方式进行安装。添加Helm仓库&#xff1a; 确保你已经添加了包含你要升级…...

复现文件上传漏洞

一、搭建upload-labs环境 将下载好的upload-labs的压缩包&#xff0c;将此压缩包解压到WWW中&#xff0c;并将名称修改为upload&#xff0c;同时也要在upload文件中建立一个upload的文件。 然后在浏览器网址栏输入&#xff1a;127.0.0.1/upload进入靶场。 第一关 选择上传文件…...

Java 内存异常

内存溢出 内存溢出指的是在程序执行过程中&#xff0c;申请的内存超过了系统实际可用的内存资源。 内存溢出的常见情况&#xff1a; 创建大量对象并持有引用&#xff1a;在程序中创建大量对象并持有对这些对象的引用&#xff0c;而没有及时释放这些引用&#xff0c;导致堆内存…...

Windows11去掉 右键菜单的 AMD Software:Adrenalin Edition 选项

Windows11去掉 右键菜单的 AMD Software:Adrenalin Edition 选项 运行regedit打开注册表编辑器 先定位到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PackagedCom\Package找到 AdvancedMicroDevicesInc-2.…...

uniapp实现我的订单页面无感 - 删除数据

在进入我们的订单页面时进行获取列表&#xff0c;上拉加载&#xff0c;下拉刷新等请求&#xff0c;我们在删除数据时&#xff0c;请求删除接口后&#xff0c;不要重新去请求数据&#xff0c;不要重新去请求数据&#xff0c;不要重新去请求数据 重新请求会刷新页面中的数据 方…...

MySQL—redo log、undo log以及MVCC

MySQL—redo log、undo log以及MVCC 首先回忆一下MySQL事务的四大特性&#xff1a;ACID&#xff0c;即原子性、一致性、隔离性和持久性。其中原子性、一致性、持久性实际上是由InnoDB中的两份日志保证的&#xff0c;一份是redo log日志&#xff0c;一份是undo log日志&#xff…...

13 list的实现

注意 实现仿cplus官网的list类&#xff0c;对部分主要功能实现 实现 文件 #pragma once #include <assert.h>namespace mylist {template <typename T>struct __list_node{__list_node(const T& x T()): _prev(nullptr), _next(nullptr), _data(x){}__lis…...

如何用client-go获取k8s因硬盘容量、cpu、内存、gpu资源不够引起的错误信息?

在Kubernetes中&#xff0c;你可以使用client-go库来获取Pod的状态和事件&#xff0c;这些信息可能包含了由于资源不足引起的错误信息。 以下是一个基本的示例&#xff0c;展示如何使用client-go来获取Pod的状态和事件&#xff1a; package mainimport ("flag"&quo…...

IDEA编译安卓源码TVBox(2)

一、项目结构&#xff1a;主要app和player app结构 二、增加遥控器按键选台 修改LivePlayActivity.java 1、声明变量 public String channelId "";public Timer timer new Timer();public Toast mToast;2、定义方法 private void mToastShow(String s){mToast …...

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…...

第十四届蓝桥杯省赛真题 Java 研究生 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 特殊日期试题 B: 与或异或试题 C: 棋盘试题 D: 子矩阵试题 E : \mathrm{E}: E: 互质数的个数试题 F: 小蓝的旅行计划试题 G: 奇怪的数试题 H: 太阳试题 I: 高塔试题 J \mathrm{J} J : 反异或 01 串 发现宝藏 前些天发现了一个巨牛的人…...

adb shell input text 输入中文

由于adb 不支持中文输入&#xff08;不支持 Unicode&#xff09;&#xff0c;需要使用虚拟键盘绕一圈。 可以直接参考和使用&#xff1a; https://github.com/senzhk/ADBKeyBoard # 通用方式 adb shell am broadcast -a ADB_INPUT_TEXT --es msg 赞 # mac/linux 支持 base64…...

Rudolf and the Ball Game

传送门 题意 思路 暴力枚举每一个妆台的转换条件 code #include<iostream> #include<cstdio> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<ma…...

计算机毕业设计-基于大数据技术下的高校舆情监测与分析

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、研究背景与意义1.1背景与意义1.2 研究内容 二、舆情监测与分析的关键技术2.1 robot协议对本设计的影响2.2 爬虫2.2.1 工作原理2.2.2 工作流程2.2.3 抓取策略2.3 scrapy架构2.3.1 scrapy&#xff1a;开源爬虫架…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...