Redis从入门到超神-(六)SpringCache操作缓存

引言

java操作Redis有很多中方案,Jedis,SpringBootDataRedis,Redisson等,本篇文章的目的是使用SpringBootDataRedis整合SpringCache基于Redis实现缓存操作

一、SpringBoot整合Redis实现缓存 

SpringBoot提供了整合Redis的方案,我们使用spring-boot-starter-data-redis包就可以很方便的操作Redis了。

1.第一步:导入redis的基础依赖
<!--整合Redis , 底层可以用jedis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions>
</dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>

spring-boot-starter-data-redis 默认使用的是lettuce操作Redis,这个技术在高并发下会有内存溢出的风险,这里我排除掉lettuce,使用jedis操作redis

2.第二步:配置redis
spring:redis:database: 0host: 127.0.0.1port: 6379password: 123456jedis:pool: #连接池max-wait: 2000ms #等待超时min-idle: 2 #最小空闲数max-idle: 8 #最大空闲数
3.第三步:配置RedisTemplate序列化方式

主要配置对象存储到Redis使用JSON格式序列化,这种格式比较通用

@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Resourceprivate RedisConnectionFactory factory;//使用JSON进行序列化@Beanpublic RedisTemplate<String, Object> redisTemplate() {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);//JSON格式序列化GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();        //value的序列化    redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);//hash结构value的虚拟化redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);return redisTemplate;}@Bean@Overridepublic CacheResolver cacheResolver() {return new SimpleCacheResolver(cacheManager());}@Bean@Overridepublic CacheErrorHandler errorHandler() {// 用于捕获从Cache中进行CRUD时的异常的回调处理器。return new SimpleCacheErrorHandler();}//缓存管理器@Bean@Overridepublic CacheManager cacheManager() {RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues() //不允许空值.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));//值使用JSON虚拟化return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build();}
} 
4.第三步:缓存流程

通过注入:RedisTemplate操作缓存,如果使用String的话也可以直接使用 StringRedisTemplate

 @Autowiredprivate RedisTemplate<String,Object> redisTemplate;//@Autowired//private StringRedisTemplate stringRedisTemplate;

缓存逻辑伪代码,先从缓存查询,如果缓存有直接返回结果,如果缓存没有就走数据库查询,然后同步到缓存再返回结果:

public User selectUserById(Long id){//从缓存查询String userKey = "user:"+id;User userFromCache = redisTemplate.opsForValue().get(userKey );if(null == userFromCache ){//缓存为空,从数据库查询User userFromDB = userDao.selectUserById(id);//把user存储到缓存redisTemplate.opsForValue().set(userKey ,userFromDB  );//返回Userreturn userFromDB ;}return userFromCache ;
}

上面代码并不完整,在数据库中的数据发送事务操作的时候,还需要把缓存中的数据剔除来保证数据一致性

public void deleteUserById(Long id){userDao.deleteUserById(id);String userKey = "user:"+id;redisTemplate.delete(userKey )
}
二.使用SpringCahe注解实现缓存
1.注解介绍

对于缓存声明,Spring的缓存提供了一组java注解:

  • @Cacheable写入缓存
  • @CacheEvict清除缓存
  • @CachePut更新缓存
  • @Caching组合多个缓存操作
  • @CacheConfig:设置类级别上共享的一些常见缓存设置
2.开启SpringCache

在启动类贴上 @EnableCaching 注解

@SpringBootApplication
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(CourseApplication.class );}
}
3.写入缓存

@Cacheable :写入缓存,打在有返回值的方法上,自动把返回值加入缓存,并且在执行方法之前会检查缓存时候有数据,如果有就直接返回缓存中的数据,不再执行方法

 //@Cacheable(cacheNames = "user",key = "'id1'")@Cacheable(cacheNames = "user",key = "#id")public User selectUserById(Long id) {return userDao.selectUserById(id);}

一个注解就实现了上面代码 1.4 中的缓存案例 ,非常方便,这里的:

  • cacheNames = “user” :指的是缓存的名字为“user”
  • key = “#id” :是值把参数id的值作为是缓存的key,“#id”是表达式写法,在Redis中会 cacheNames 和 key 联合起来作为 键 ,效果如:“user::1” 

常见的用法:

  • @Cacheable(cacheNames = “user”,key = “‘id1’”) :固定一个key 效果如:“user:id1”
  • @Cacheable(cacheNames = “user”,key = “#obj.id”) :取参数obj对象的id的值作为key ,效果如:“user::1”
  • @Cacheable(cacheNames = “user”,key = “#id”,condition="#id > 10") : 需要满足id大于10才做缓存
4.删除缓存

在数据库做了事务操作(增删改),需要把缓存中的数据删除,等待下一次查询重新同步缓存数据,在SpringCache中可以使用 @CacheEvict 注解完成,他会主动匹配key完成缓存的剔除工作

@CacheEvict(cacheNames = "user",key = "#id")
public void deleteUserById(Long id){userDao.deleteUserById(id);
}

如果要对缓存批量删除可以使用 @CacheEvict(cacheNames="user", allEntries=true)

5.更新缓存

更新缓存使用@CachePut注解,和@Cacheable用法相同,他会把方法的返回值自动更新到缓存,以注解的key做自动匹配

@CachePut(cacheNames = "user",key = "#user.id")
public User updateUserById(User user){userDao.updateUserById(user);return user;
}

注意:建议不要把@CachePut和@Cacheable作用于同一个方法,可能会有功能上的冲突

6.组合操作

@Caching注解可以组合多个缓存操作,比如删除多个缓存

//删除多个缓存,user和其账户一起删除
@Caching(evict = { @CacheEvict(cacheNames="user", key = "#user.id"), @CacheEvict(cacheNames="account", key = "#user.id") })
public void updateUserById(User user){userDao.updateUserById(user);return user;
}
7.公共配置

@CacheConfig注解可以配置一些共享的属性,比如把cacheNames抽取出来

@CacheConfig(cacheName="user") 
public class CacheService{@CacheEvict(key = "#id")public void deleteUserById(Long id){userDao.deleteUserById(id);}@CachePut(key = "#user.id")public User updateUserById(User user){userDao.updateUserById(user);return user;}
}

文章结束啦,如果对你有帮助请一定给个好评哦~~~

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

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

相关文章

Llama 3.1要来啦?!测试性能战胜GPT-4o

哎呀&#xff0c;Meta声称将于今晚发布的Llama 3.1&#xff0c;数小时前就在Hugging Face上泄露出来了&#xff1f;泄露的人很有可能是Meta员工&#xff1f; 还是先来看泄露出来的llama3.1吧。新的Llama 3.1模型包括8B、70B、405B三个版本。 而经过网友测试&#xff0c;该base…

Spark实时(二):StructuredStreaming编程模型

文章目录 StructuredStreaming编程模型 一、基础语义 二、事件时间和延迟数据 三、​​​​​​​​​​​​​​容错语义 StructuredStreaming编程模型 一、基础语义 Structured Streaming处理实时数据思想是将实时数据看成一张没有边界的表&#xff0c;数据源源不断的追…

年化22.8%的单因子分析:基于Alphalens做可转债全市场数据的单因子分析(附python代码+全量数据)

原创文章第597篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 因子分析是量化研究的基本技能之一。通过因子分析&#xff0c;找出有效的因子&#xff0c;通过相关性去重后&#xff0c;就可以通过机器学习、线性回归等方法把因子组合起来&#xf…

Linux基础学习day1

1.Linux系统介绍 1.常见的操作系统 1.Windows&#xff08;NT内核&#xff09;不开源 2.ubantu&#xff08;linux内核&#xff09; 3.ios&#xff08;unix内核&#xff09;不开源 4.鸿蒙&#xff08;兼容linux内核&#xff09; 5.Android&#xff08;linux内核&#xff09…

STM32(七):STM32指南者-通信实验

目录 一、基本概念通讯基本概念1、串行和并行2、同步通讯与异步通讯3、全双工、半双工、单工4、通讯速率 USART基本概念1、串口通讯基本概念2、物理层3、协议层4、指南者的串口USART I2C基本概念SPI基本概念 二、USART串口实验前期准备1、安装安装 USB 转串口驱动_CH3402、野火…

Git之repo sync -l与repo forall -c git checkout用法区别(四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

微信各平台历史版本含下载地址大全( 安卓 | Windows | MAC )

微信-windows-版本历史 https://github.com/tom-snow/wechat-windows-versions/releases 微信-windows-x86版本历史 https://github.com/tom-snow/wechat-windows-versions-x86/releases 微信安卓版本历史 https://github.com/DJB-Developer/wechat-android-history-version…

Apache DolphinScheduler 3.2.2 版本正式发布!

Apache DolphinScheduler 3.2.2 版本正式发布&#xff01; 近日&#xff0c;Apache DolphinScheduler 发布了 3.2.2 版本。此版本主要基于 3.2.1 版本进行了 bug 修复&#xff0c;新增若干特性&#xff0c;并进行了众多改进和 Bug 修复&#xff0c;以及文档修复等。 &#x1…

OAuth 2.0

OAuth 2.0&#xff08;Open Authorization 2.0&#xff09;是一种开放标准的授权协议&#xff0c;它允许第三方应用程序以安全可控的方式访问受保护的资源&#xff0c;而无需用户将用户名和密码信息与第三方应用程序共享。 一、设计原则 OAuth 2.0的设计旨在解决OAuth 1.0中的…

电路学习——经典运放电路之滞回比较器(施密特触发器)(2024.07.18)

参考链接1: 电子设计教程29&#xff1a;滞回比较器&#xff08;施密特触发器&#xff09; 参考链接2: 滞回比较器电路详细分析 参考链接3: 比较器精髓&#xff1a;施密特触发器&#xff0c;正反馈的妙用 参考链接4: 比较器反馈电阻选多大&#xff1f;理解滞后效应&#xff0c;轻…

【iOS】进程与多线程

目录 前言进程和线程进程和线程的区别多线程的意义时间片概念 线程的生命周期线程池的运行策略自旋锁和互斥锁自旋锁互斥锁自旋锁和互斥锁区别原子属性 iOS多线程技术方案 前言 学习此文&#xff1a;iOS多线程 在平时的iOS开发中&#xff0c;多线程是我们常会遇到的&#xff0…

新手教学系列——如何在MacOS 10.13.6(老系统)手动安装和配置Pyenv

前言 对于使用老旧系统&#xff08;如MacOS 10.13.6&#xff09;的用户来说&#xff0c;安装和管理Python版本可能会遇到一些挑战。特别是由于Homebrew不再支持老系统&#xff0c;许多软件安装变得困难重重。本文将详细介绍如何在这样的环境下手动安装和配置Pyenv&#xff0c;…

BGP选路之Next Hop

原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时&#xff0c;BGP协议会对这些BGP路由的属性进行比较,以确定出去往该目标网络的最优BGP路由,然后将该最优BGP路由与去往同一目标网络的其他协议路由进行比较&#xff0c;从而决定是否将该最优BGP路由放进P路由表中…

数据代理实践

1&#xff0c;什么事数据代理机制&#xff1f; 通过访问 代理对象的属性 来向该访问 目标对象的属性 数据代理机制的视线需要依靠&#xff0c;Object.defineProperty()方法 2&#xff0c; ES6新特性&#xff1a; 在对象中的函数/方法 &#xff1a;function是可以省略的 &l…

宝塔国际版Docker Manager 3.4获取镜像列表报错解决办法

宝塔国际版安装Docker Manager 3.4,遇到获取镜像列表的时候报错。 解决办法 找到:/www/server/panel/plugin/docker/docker_main.py文件 替换函数utc_to_local 原代码 # UTC时间转换为时间戳def utc_to_local(self, utc_time_str, utc_format=%Y-%m-%dT%H:%M:%S):

Android 各个版本兼容型问题

Android 6.0 新增运行时权限&#xff0c;危险权限需要动态申请。 Android 7.0 Android 8.0 允许安装未知来源应用&#xff0c;需要在 AndroidManifest.xml 中声明 REQUEST_INSTALL_PACKAGES 权限。Android8.0取消隐式广播&#xff0c;移除掉了所有的隐式广播。 Android 9.0…

机器学习(五) -- 无监督学习(1) --聚类2

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 无监督学习&#xff08;1&#xff09; --聚类1 下篇&#xff1a; 前言 tips&#xff1a;标题前有“***”的内容为补充内容&#xff0c;是给好奇心重的宝宝看的&#xff0c;可自行跳过。文章内容被…

2个案例区分是平行眼还是交叉眼,以及平行眼学习方法

案例一&#xff1a; 交叉眼&#xff1a;看到凸出的“灌水”&#xff0c;是交叉眼。PS&#xff1a;看的时候&#xff0c;眼是斗鸡眼&#xff0c;眼睛易疲劳 平行眼&#xff1a;看到凹陷的“灌水”&#xff0c;是平行眼。PS&#xff1a;看的时候眼睛是平视&#xff0c;不容易疲…

TFHE中的数据结构Torus

点个关注吧&#xff01;&#xff01; 一、理论概念 Torus是一个 [ 0 , 1 ) [0,1) [0,1)的集合&#xff08;数模1运算&#xff09;。取值范围通常有符号实数&#xff1a; [ − 1 / 2 , 0 ) ∪ [ 0 , 1 / 2 ) [-1/2,0)\cup [0,1/2) [−1/2,0)∪[0,1/2) 本文用T表示Torus。 T满足…

sqlalchemy使用mysql的json_extract函数查询JSON字段

sqlalchemy使用mysql的json_extract函数查询JSON字段 在SQLAlchemy中,如果你想要在MySQL中存储JSON字段,并且进行查询操作,可以按照以下步骤进行设置和查询: 1. 创建表格 首先,创建一个表格来存储包含JSON字段的数据。假设我们有一个名为 users 的表格,其中有一个名为…