Redis的操作以及SpringCache框架

目录

一.什么是Redis?

二.Redis的相关知识:

三.如何操作Redis?

1,常用命令:

2.Spring Data Redis

(1) pom.xml 配置:

(2)配置Redis数据源:

(3)编写配置类,创建RedisTemplate对象:

(4)通过RedisTemplate对象操作Redis:

四.SpringCache框架:

1.什么是SpringCache框架?

2.SpringCache框架的相关注解:

 3.SpringCache框架的使用:

(1)pom.xml文件:

(2)在启动类上家@EnableCaching注解来开启缓存注解功能

(3)三个注解的使用:

2.@Cacheable:

3.@CacheEvict:


引言:本内容与B站黑马的苍穹外卖项目配套,总结一些Redis的知识点以及苍穹外卖项目的代码解析,希望该内容能给你带来帮助......

一.什么是Redis?

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。

在同一个时间段内,向数据库进行大量操作(例如:添加大量的内容),就会频繁的查询数据库,导致数据库访问压力过大,最终导致系统响应慢、体验差,这个时候我们就需要使用Redis来缓解数据库的压力。

二.Redis的相关知识:

Redis是通过键值对的形式存储数据(key-value)。

key ->字符串

value -> String(字符串) , hash(哈希/散列) , list(有序列表,相当于Java的队列,可重复) , set(集合,无需不可重) , zset(集合,有序不可重)

想要进阶可以查看下面的博客:

Redis?它主要用来什么的-CSDN博客

下面是Redis的操作过程

优点:

  • 加快了响应速度
  • 减少了对数据库的读操作,数据库的压力降低

缺点:

  • 内存容量相对硬盘小

  • 缓存中的数据可能与数据库中数据不一致

  • 内存断电就会清空数据,造成数据丢失

三.如何操作Redis?

1,常用命令:

我们先下载Windows版的redis安装包进行安装,然后在cmd命令行中输入redis-server.exe redis.windows.conf,然后在打开新的cmd运行redis-cli.exe -h localhost -p 6379 -a 密码,当Redis服务启动成功后,可通过客户端进行连接。

我们也是有像操作MySQL一样的命令来操作Redis,这里给大家分享Redis图形化工具Another Redis Desktop Manager

这个常用命令就不过多叙述了...

2.Spring Data Redis

Spring Data Redis ->Redis的Java客户端,以至于我们可以在idea利用Java代码来操作Redis。

(1) pom.xml 配置:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2)配置Redis数据源:

在application.yml文件中:

spring:redis:host: localhost   #ipport: 6379        #端口号password: ******  #Redis的密码database: 0       #指定使用哪个数据源(可不写,但默认是DB0)

(3)编写配置类,创建RedisTemplate对象:

我们使用RedisTemplate这个类对象内封装的方法来操作Redis,所以我们在配置类内创建RedisTemplate并用Bean注解将其交给Spring容器管理。

@Configuration
@Slf4j
public class RedisConfiguration {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){log.info("开始创建Redis模板对象...0");RedisTemplate redisTemplate = new RedisTemplate();//设置redis的连接工厂对象redisTemplate.setConnectionFactory(redisConnectionFactory);//设置redis key的序列化器,这里反应的是Redis图形化工具上value值的不同redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;}
}

(4)通过RedisTemplate对象操作Redis:

String类型:redisTemplate.opsForValue()

hash类型:redisTemplate.opsForHash()

list类型:redisTemplate.opsForList()

set类型:redisTemplate.opsForSet()

zset类型:redisTemplate.opsForZSet()

其内部封装有相关操作Redis的方法,可以通过依赖注入的方式调用相关方法。

下面可以看一下测试类操作String类型来理解一下:

@SpringBootTest
public class SpringDataRedisTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testString(){redisTemplate.opsForValue().set("city","北京");String city = (String)redisTemplate.opsForValue().get("city");System.out.println(city);redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);redisTemplate.opsForValue().setIfAbsent("lock","1");redisTemplate.opsForValue().setIfAbsent("lock","2");}
}

根据黑马苍穹外卖的业务代码(查询操作)来具体理解一下:

@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<DishVO>> list(Long categoryId) {//构造redis中的key,规则:dish_分类idString key = "dish_" + categoryId;//查询redis中是否存在菜品数据List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);//判断是否存在缓存if(list != null && list.size() > 0){return Result.success(list);}//如果不存在缓存Dish dish = new Dish();dish.setCategoryId(categoryId);dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品list = dishService.listWithFlavor(dish);//将查询到的数据放入redis缓存中redisTemplate.opsForValue().set(key,list);return Result.success(list);}
}

四.SpringCache框架:

1.什么是SpringCache框架?

基于注解的使用来操作Redis的框架。

2.SpringCache框架的相关注解:

  • @Cacheable:在方法执行前查看是否有缓存对应的数据,如果有直接返回数据,如果没有调用方法获取数据返回,并缓存起来。
  • @CacheEvict:将一条或多条数据从缓存中删除。
  • @CachePut:将方法的返回值放到缓存中
  • @EnableCaching:开启缓存注解功能

 3.SpringCache框架的使用:

(1)pom.xml文件:

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

(2)在启动类上家@EnableCaching注解来开启缓存注解功能

@SpringBootApplication
@EnableCaching //开发缓存注解功能
@Slf4j
public class SkyApplication {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info("server started");}
}

(3)三个注解的使用:

我们在介绍这三个注解前需要知道使用注解后存入Redis的key值是什么?

这个时候就需要介绍 cacheNames,key,allEntries:

用@CachePut举例子(共五种表示方法):

①.

@CachePut(cacheNames = "名字" , key = "#形参.形参内属性") 
//key的生成为:名字::属性值

 eg:

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;@PostMapping@CachePut(cacheNames = "userCache" , key = "#user.id") //key的生成为:userCache::2public User save(@RequestBody User user){userMapper.insert(user);return user;}
}

②p0代表第一个形参

@CachePut(cacheNames = "名字" , key = "#p0.属性") 
//key的生成为:名字::属性值

③a0代表第一个形参

@CachePut(cacheNames = "名字" , key = "#a0.属性") 
//key的生成为:名字::属性值

④root.args[0]代表第一个形参

@CachePut(cacheNames = "名字" , key = "#root.args[0].属性") 
//key的生成为:名字::属性值

⑤result是代表返回值

@CachePut(cacheNames = "名字" , key = "#result.属性") 
//key的生成为:名字::属性值

随后还要注意@Cacheable不能使用result

1.@CachePut:

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;@PostMapping@CachePut(cacheNames = "userCache" , key = "#user.id") //key的生成为:userCache::2public User save(@RequestBody User user){userMapper.insert(user);return user;}
}
2.@Cacheable:
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;@GetMapping@Cacheable(cacheNames = "userCache" , key = "#id")public User getById(Long id){User user = userMapper.getById(id);return user;}
}
3.@CacheEvict:

删除一条数据时:

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;@DeleteMapping@CacheEvict(cacheNames = "userCache" ,  key = "#id")public void deleteById(Long id){userMapper.deleteById(id);}
}

删除多条数据时:allEntries翻译为所有键值对

@RestController
@RequestMapping("/admin")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;@PutMapping@ApiOperation("修改套餐")@CacheEvict(cacheNames = "setmealCache" , allEntries = true)public Result update(@RequestBody SetmealDTO setmealDTO){setmealService.update(setmealDTO);return Result.success();}
}

 五.实战应用:

1.设置店铺状态:

如果我们想设置一个餐厅是营业状态还是打烊,我们可以设置Integer status属性封装状态,并在Redis中创建key-value,之后获取可以在Redis获取。

@RestController("adminShopController")
@RequestMapping("/admin/shop")
@Api(tags = "店铺相关接口")
@Slf4j
public class ShopController {public static final String KEY = "SHOP_STATUS";@Autowiredprivate RedisTemplate redisTemplate;/*** 设置店铺的营业状态* @param status* @return*/@PutMapping("/{status}")@ApiOperation("设置店铺的营业状态")public Result setStatus(@PathVariable Integer status){log.info("设置店铺的营业状态为:{}",status == 1 ? "营业中" : "打烊中");redisTemplate.opsForValue().set(KEY,status);return Result.success();}/*** 获取店铺的营业状态* @return*/@GetMapping("/status")@ApiOperation("获取店铺的营业状态")public Result<Integer> getStatus(){Integer status = (Integer)redisTemplate.opsForValue().get(KEY);log.info("获取店铺的营业状态:{}",status == 1 ? "营业中" : "打烊中");return Result.success(status);}
}

 2.用户查询菜品的Redis缓存操作:

将查询过的结果缓存,以便于下次直接在Redis中获得缓存来减少数据库的压力 

(1)将用户最开始首次进入页面执行的接口设置@Cacheable,能够直接将回调的数据在Redis缓存,以便下一次直接通过注解的作用直接返回数据,而无需调用接口内方法:

@RestController("userSetmealController")
@RequestMapping("/user/setmeal")
@Api(tags = "C端-套餐浏览接口")
public class SetmealController {@Autowiredprivate SetmealService setmealService;/*** 条件查询** @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询套餐")@Cacheable(cacheNames = "setmealCache" , key = "#categoryId")  //key为 setmealCache::100public Result<List<Setmeal>> list(Long categoryId) {Setmeal setmeal = new Setmeal();setmeal.setCategoryId(categoryId);setmeal.setStatus(StatusConstant.ENABLE);List<Setmeal> list = setmealService.list(setmeal);return Result.success(list);    }
}

 (2)在商家想要进行增删改的操作,以及与菜品可能会出现缓存问题的接口进行清空缓存,以免缓存与更改后的数据不一致造成错误:(方法删除)

下面的代码为对菜品增删改,以及菜品起售停售进行清空缓存,为了节省以及美观,这里封装了cleanCache()方法,随后仅需要传递形参也就是想要删除的缓存的key格式,然后调用方法redisTemplate.keys(key)获得所有该格式下的key并用set集合封装,随后调用delete方法删除所有key就可以达到清空缓存的目的

@RestController
@RequestMapping("/admin/dish")
@Api(tags = "菜品相关接口")
@Slf4j
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;/*** 封装的清理缓存数据方法* @param patten*/private void cleanCache(String patten){//清理删除的菜品缓存Set keys= redisTemplate.keys(patten);//将所有以dish_的格式的key获取出来redisTemplate.delete(keys);}/*** 新增菜品* @param dishDTO* @return*/@PostMapping@ApiOperation("新增菜品")public Result save(@RequestBody DishDTO dishDTO){log.info("新增菜品:{}",dishDTO);dishService.saveWithFlavor(dishDTO);//清理缓存String key = "dish_" + dishDTO.getCategoryId();cleanCache(key);return Result.success();}/*** 菜品的批量删除* @param ids* @return*/@DeleteMapping@ApiOperation("菜品的批量删除")public Result delete(@RequestParam List<Long> ids){log.info("菜品的批量删除:{}",ids);dishService.deleteBatch(ids);//清理删除的菜品缓存cleanCache("dish_*");return Result.success();}/*** 修改菜品* @param dishDTO* @return*/@PutMapping@ApiOperation("修改菜品")public Result update(@RequestBody DishDTO dishDTO){log.info("修改菜品,{}",dishDTO);dishService.updateWithFlavor(dishDTO);//清理缓存数据//清理删除的菜品缓存cleanCache("dish_*");return Result.success();}/*** 菜品起售停售* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("菜品起售停售")public Result<String> startOrStop(@PathVariable Integer status, Long id){dishService.startOrStop(status,id);//清理删除的菜品缓存cleanCache("dish_*");return Result.success();}
}

(3)在商家想要进行增删改的操作,以及与套餐可能会出现缓存问题的接口进行清空缓存,以免缓存与更改后的数据不一致造成错误:(注解删除)

跟上面的一样,只不过这次使用我们SpringCache框架的注解来进行清空缓存的操作。

@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;/*** 新增套餐* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")@CacheEvict(cacheNames = "setmealCache" , key = "#setmealDTO.categoryId") //key为 setmealCache::100public Result save(@RequestBody SetmealDTO setmealDTO){setmealService.saveWithDish(setmealDTO);return Result.success();}/*** 批量删除套餐* @return*/@DeleteMapping@ApiOperation("批量删除套餐")@CacheEvict(cacheNames = "setmealCache" , allEntries = true)public Result delete(@RequestParam List<Long> ids){setmealService.deleteBatch(ids);return Result.success();}/*** 修改套餐* @param setmealDTO* @return*/@PutMapping@ApiOperation("修改套餐")@CacheEvict(cacheNames = "setmealCache" , allEntries = true)public Result update(@RequestBody SetmealDTO setmealDTO){setmealService.update(setmealDTO);return Result.success();}/*** 套餐起售停售* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("套餐起售停售")@CacheEvict(cacheNames = "setmealCache" , allEntries = true)public Result startOrStop(@PathVariable Integer status, Long id) {setmealService.startOrStop(status, id);return Result.success();}
}

好了,Redis的操作大致内容就这些,读完可以了解缓存击穿、缓存穿透、缓存雪崩这三个问题,今天内容就到这里,感谢收看!!!

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

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

相关文章

转置卷积 transposed convolution

1. 转置卷积 转置卷积&#xff08;Transposed Convolution&#xff09;也叫Fractionally-strided Convolution和Deconvolution&#xff0c;但用的最多的是Transposed Convolution。 注意&#xff1a; 转置卷积不是卷积的逆运算&#xff0c;只会大小恢复为原本大小。转置卷积…

SPSS个人版是什么软件

SPSS是一款数据统计、分析软件&#xff0c;它由IBM公司出品&#xff0c;这款软件平台提供了文本分析、大量的机器学习算法、数据分析模型、高级统计分析功能等&#xff0c;软件易学且功能非常强大&#xff0c;可以使用SPSS制作图表&#xff0c;例如柱状、饼状、折线等图表&…

APP逆向 day21大姨妈逆向

一.前言 今天来和大家说一款app名叫DYM&#xff0c;我们选择版本v8.6.0&#xff0c;今天通过这个可以学到的知识点有绕过root检测&#xff0c;通过frida-rpc和自己编写一款小的app来调用so文件&#xff0c;然后再来破解登录接口 二.绕过root检测 我们进入app后发现&#xff…

C++从入门到起飞之——初始化列表类型转换static成员 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、初始化列表 2、 类型转换 3. static成员 4、完结散花 1、初始化列表 • 之前我们实现构造函数…

Qwen2模型Text2SQL微调​以及GGUF量化

Qwen2-1.5B微调 准备python环境 conda create --name llama_factory python=3.11 conda activate llama_factory部署llama-factory git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip3 install -e ".[torch,metrics]" # 如…

算法日记day 20(二叉搜索树)

一、验证二叉搜索树 题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也…

IE11添加收藏、关闭窗口时弹出的对话框字体又大又粗很难看的解决办法

原因已查明&#xff0c;在win7 sp1 32位系统下&#xff0c;安装“2020-01 适用于基于 x86 的系统的 Windows 7 月度安全质量汇总&#xff08;KB4534310&#xff09;”这个更新会导致IE11的窗口字体变大变粗&#xff0c;把这个更新卸载了就可以了&#xff0c;无需重装IE11浏览器…

【四】jdk8基于m2芯片arm架构Ubuntu24虚拟机下载与安装

文章目录 1. 安装版本2. 开始安装3. 集群安装 1. 安装版本 如无特别说明&#xff0c;本文均在root权限下安装。进入oracle官网&#xff1a;https://www.oracle.com/java/technologies/downloads/找到最下面Java SE 看到java 8&#xff0c;下载使用 ARM64 Compressed Archive版…

探索 Electron:快捷键与剪切板操作

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

C++:类和对象2

1.类的默认成员函数 默认成员函数就是用户没有显示实现编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;我们在不写的情况下编译器会默认生成6个默认成员函数&#xff0c;分别是构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;拷贝赋值运算…

GPT-4引领:AI新浪潮的转折点

OneFlow编译 **翻译&#xff5c;贾川、杨婷、徐佳渝 编辑&#xff5c;王金许** 一朝成名天下知。ChatGPT/GPT-4相关的新闻接二连三刷屏朋友圈&#xff0c;如今&#xff0c;这些模型背后的公司OpenAI的知名度不亚于任何科技巨头。 不过&#xff0c;就在ChatGPT问世前&#x…

Reaxys平台账号创建:简易注册流程

Reaxys数据库是Elsevier旗下的全球最大物质理化性质和事实反应数据库&#xff0c;包含了超过5亿条经过实验验证的物质信息&#xff0c;收录超过1.38亿种化合物&#xff0c;5,000万种单步和多步反应、6,000万条文摘记录。涵盖全球7大专利局和16,000种期刊16个学科中与化合物性质…

全网最详细Gradio教程系列5——Gradio Client: python

全网最详细Gradio教程系列5——Gradio Client: python 前言本篇摘要5. Gradio Client的三种使用方式5.1 使用Gradio Python Client5.1.1 安装gradio_client5.1.2 连接Gradio应用程序1. 通过URL连接2. 通过SpaceID连接3. 辅助&#xff1a;duplicate()和hf_token4. Colab Noteboo…

ajax学习1

<!-- 目标&#xff1a;使用axios库&#xff0c;获取省份列表数据&#xff0c;展示到页面上 1.引入axios库 --> <p class"my-p"></p> <script src"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></ script> <sc…

Tomcat项目本地部署

今天来分享一下如何于本机上在不适用idea等辅助工具的前提下&#xff0c;部署多个tomcat的web项目 我这里以我最近写的SSM项目哈米音乐为例&#xff0c;简单介绍一下项目的大致组成&#xff1a; 首先&#xff0c;项目分为4个模块&#xff0c;如下图所示&#xff1a; 其中&…

力扣高频SQL 50题(基础版)第十八题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第十八题1633. 各赛事的用户注册率题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第十八题 1633. 各赛事的用户注册率 题目说明 用户表&#xff1a; Users --…

RPG素材Unity7月20闪促限时4折游戏开发资产兽人角色模型动画休闲放置模板物理交互流体水下焦散VR界面UI2D模板场景20240720

今天这个是RPG素材比较多&#xff0c;还有一些休闲放置模板、FPS场景素材、角色模型、动画、特效。 详细内容展示&#xff1a;www.bilibili.com/video/BV1Tx4y1s7vm 闪促限时4折&#xff1a;https://prf.hn/l/0eEOG1P 半价促销&#xff1a;https://prf.hn/l/RlDmDeQ 7月闪促…

小红书(社招二面)算法原题

萝卜快跑涨价 距离我们上次谈 萝卜快跑 不足半月&#xff0c;萝卜快跑迎来了不少"反转"。 先是被曝远程后台有人操控&#xff0c;真实日成本超 400&#xff1a; 最近还被不少网友吐槽&#xff1a;萝卜快跑涨价了&#xff0c;如今价格和网约车持平。 据不少博主实测&a…

17 Python常用内置函数——基本输入输出

input() 和 print() 是 Python 的基本输入输出函数&#xff0c;前者用来接收用户的键盘输入&#xff0c;后者用来把数据以指定的格式输出到标准控制台或指定的文件对象。无论用户输入什么内容&#xff0c;input() 一律作为字符串对待&#xff0c;必要时可以使用内置函数 int()、…

【SpringBoot教程:从入门到精通】掌握Springboot开发技巧和窍门(四)-Vue项目配置环境、导航栏

主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; 文章目录 前言 Vue项目配置环境 安装依赖 创建菜单 总结 前言 主要写前端页面&#xff0c;采用vue框架写页面的导航栏&#xff01;&#xff01;&#xff01; Vue项目配置环境 安装…