redis spring cache
数据库的数据是存储在硬盘上的,频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中,可以大大减轻数据库的访问压力。
SpringCache
SpringCache提供基本的Cache抽象,并没有具体的缓存能力,需要配合具体的缓存实现来完成,目前SpringCache支持redis、ehcache、simple(基于内存)等方式来实现缓存。
org.springframework.boot spring-boot-starter-cache1
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
数据库的数据是存储在硬盘上的,频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中,可以大大减轻数据库的访问压力。 SpringCache SpringCache提供基本的Cache抽象,并没有具体的缓存能力,需要配合具体的缓存实现…...
图解I/O中的零拷贝技术
什么是零拷贝? 零拷贝是一种计算机系统中的 I/O 优化技术,它的核心思想是在数据传输过程中尽可能地减少或完全避免 CPU 将数据从一个存储区域复制到另一个存储区域的操作,从而减少了上下文切换和 CPU 拷贝时间,提高了系统的性能和…...
【设计模式】Java 设计模式之桥接模式(Bridge)
桥接模式(Bridge Pattern)是结构型设计模式的一种,它主要解决的是抽象部分与实现部分的解耦问题,使得两者可以独立变化。这种类型的设计模式属于结构型模式,因为该模式涉及如何组合接口和它们的实现。将抽象部分与实现…...
记录dockers中Ubuntu安装python3.11
参考: docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客...
【算法专题--双指针算法】leetcode--283. 移动零、leetcode--1089. 复写零
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 前言1. 移动零࿰…...
【JavaEE -- 多线程3 - 多线程案例】
多线程案例 1.单例模式1.1 饿汉模式的实现方法1.2 懒汉模式的实现方法 2. 阻塞队列2.1 引入生产消费者模型的意义:2.2 阻塞队列put方法和take方法2.3 实现阻塞队列--重点 3.定时器3.1 定时器的使用3.2 实现定时器 4 线程池4.1 线程池的使用4.2 实现一个简单的线程池…...
k8s的pod服务升级,通过部署helm升级
要通过Helm升级Kubernetes(k8s)中的Pod服务,你可以按照以下步骤进行操作: 安装Helm: 如果你还没有安装Helm,可以通过官方文档提供的方式进行安装。添加Helm仓库: 确保你已经添加了包含你要升级…...
复现文件上传漏洞
一、搭建upload-labs环境 将下载好的upload-labs的压缩包,将此压缩包解压到WWW中,并将名称修改为upload,同时也要在upload文件中建立一个upload的文件。 然后在浏览器网址栏输入:127.0.0.1/upload进入靶场。 第一关 选择上传文件…...
Java 内存异常
内存溢出 内存溢出指的是在程序执行过程中,申请的内存超过了系统实际可用的内存资源。 内存溢出的常见情况: 创建大量对象并持有引用:在程序中创建大量对象并持有对这些对象的引用,而没有及时释放这些引用,导致堆内存…...
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实现我的订单页面无感 - 删除数据
在进入我们的订单页面时进行获取列表,上拉加载,下拉刷新等请求,我们在删除数据时,请求删除接口后,不要重新去请求数据,不要重新去请求数据,不要重新去请求数据 重新请求会刷新页面中的数据 方…...
MySQL—redo log、undo log以及MVCC
MySQL—redo log、undo log以及MVCC 首先回忆一下MySQL事务的四大特性:ACID,即原子性、一致性、隔离性和持久性。其中原子性、一致性、持久性实际上是由InnoDB中的两份日志保证的,一份是redo log日志,一份是undo log日志ÿ…...
13 list的实现
注意 实现仿cplus官网的list类,对部分主要功能实现 实现 文件 #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中,你可以使用client-go库来获取Pod的状态和事件,这些信息可能包含了由于资源不足引起的错误信息。 以下是一个基本的示例,展示如何使用client-go来获取Pod的状态和事件: package mainimport ("flag"&quo…...
IDEA编译安卓源码TVBox(2)
一、项目结构:主要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讲堂》 大家好,我是全栈小5。 这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。…...
第十四届蓝桥杯省赛真题 Java 研究生 组【原卷】
文章目录 发现宝藏【考生须知】试题 A: 特殊日期试题 B: 与或异或试题 C: 棋盘试题 D: 子矩阵试题 E : \mathrm{E}: E: 互质数的个数试题 F: 小蓝的旅行计划试题 G: 奇怪的数试题 H: 太阳试题 I: 高塔试题 J \mathrm{J} J : 反异或 01 串 发现宝藏 前些天发现了一个巨牛的人…...
adb shell input text 输入中文
由于adb 不支持中文输入(不支持 Unicode),需要使用虚拟键盘绕一圈。 可以直接参考和使用: 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…...
计算机毕业设计-基于大数据技术下的高校舆情监测与分析
收藏和点赞,您的关注是我创作的动力 文章目录 概要 一、研究背景与意义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:开源爬虫架…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
