当前位置: 首页 > 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;开源爬虫架…...

WPF使用LiveCharts画图时,横坐标转换成时间

一、背景 使用LiveCharts画图时&#xff0c;横坐标通常为数值类型&#xff0c;要转换成时间等自定义类型&#xff0c;需要用到Formatter进行类型转换。 示例使用MVVM模式编写 二、View代码 关键是设置LabelFormatter属性 <lvc:CartesianChart Series"{Binding Series…...

Qt客户端开发的技术难点

在Qt客户端开发中&#xff0c;可能会遇到一些技术难点&#xff0c;这些难点可能与UI设计、性能优化、跨平台兼容性等方面有关。以下是一些可能的技术难点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…...

杰理AD155儿童玩具语音集成电路

一、杰理AD155集成电路是由杰理科技设计、开发和销售的一款产品&#xff0c;AD15系列 SoC 芯片支持以下特性&#xff1a; 工作电压&#xff1a;2.0V-5.5V主频可达120MHz的32bitCPU,片上集成20K字节SRAM&#xff0c;8K字节ICache支持最多2路解码同时运行&#xff0c;支持F1A/A/…...

git bash 命令行反应慢、卡顿(定位出根本原因)

参考该博主&#xff1a; https://blog.csdn.net/weixin_50212044/article/details/131575987?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131575987-blog-130024908.235v43pc_blog_bottom_relevance_base4&spm1001.210…...

Android 启动service(Kotlin)

一、使用startForegroundService()或startService&#xff08;&#xff09;启用service **Activity //启动service val intent: Intent Intent(ServiceActivitythis,MyService::class.java) //Build.VERSION_CODES.O 26 // Android8以后&#xff0c;不允许后台启动Service i…...

Windows蓝牙驱动开发之模拟HID设备(一)(把Windows电脑模拟成蓝牙鼠标和蓝牙键盘等设备)

by fanxiushu 2024-03-14 转载或引用请注明原作者 把Windows电脑模拟成蓝牙鼠标和蓝牙键盘&#xff0c;简单的说&#xff0c;就是把笨重的PC电脑当成鼠标键盘来使用。 这应该是一个挺小众的应用&#xff0c;但有时感觉也应该算比较好玩吧&#xff0c; 毕竟实现一种一般人都感觉…...

LlamaParse: 高效的PDF文件RAG解析工具

LlamaParse: 高效的PDF文件RAG解析工具 通过Thomas Reid的深入探索&#xff0c;LlamaParse成为了目前我所见最优秀的RAG实现用PDF解析器。基于AI的技术&#xff0c;尤其在处理像SEC Q10这样的复杂文件时表现出色&#xff0c;这些文件通常包含文本、数字及其组合构成的表格&…...

platform设备注册驱动模块的测试

一. 简介 上一篇文章编写了 platform设备注册代码&#xff0c;文章地址如下&#xff1a; 无设备树platform驱动实验&#xff1a;platform设备注册代码实现-CSDN博客 本文继续无设备树platform驱动实验&#xff0c;本文对编译好的 设备注册程序进行测试&#xff0c;测试所实…...

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItemGroup)

该组件用来展示列表item分组&#xff0c;宽度默认充满List组件&#xff0c;必须配合List组件来使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List。 使用说明 当List…...

Docker:常用命令

文章目录 docker作用常用指令 docker 作用 Docker 是一种容器化平台&#xff0c;可以让开发者打包应用程序及其依赖项&#xff0c;并以容器的形式进行发布、交付和运行。 Docker 的一些主要作用&#xff1a; 应用程序隔离&#xff1a;Docker 使用容器技术&#xff0c;将应用程…...