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

【spring boot】在Java中操作缓存:

文章目录

        • 一、Jedis
        • 二、Spring Data Redis(常用)
            • 【1】pom.xml
            • 【2】application.yml
            • 【3】RedisConfig
            • 【4】RuiJiWaiMaiApplicationTests
        • 三、Spring Cache
          • 【1】常用注解:
          • 【2】使用案例
          • 【3】底层不使用redis,重启服务,内存丢失=>解决:
            • pom.xml
            • application.yml
            • 启动类:
            • Result:
            • 注解使用:


一、Jedis

在这里插入图片描述

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version>
</dependency>
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>

在这里插入图片描述

二、Spring Data Redis(常用)

【1】pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
【2】application.yml

在这里插入图片描述

spring:redis:    #redis配置host: localhostport: 6379#password:database: 0   #默认提供16个数据库,0:0号数据库jedis:pool:  #redis连接池配置max-active: 8   #最大连接数max-idle: 4     #最大空闲连接max-wait: 1ms   #最大阻塞等待时间min-idle: 0     #最小空闲连接

在这里插入图片描述

【3】RedisConfig
package com.example.ruijiwaimai.config;import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig extends CachingConfigurerSupport {@Beanpublic RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();// 默认的key序列化器为:JdkSerializationRedisSerializerredisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}
}
【4】RuiJiWaiMaiApplicationTests
package com.example.ruijiwaimai;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;@SpringBootTest
class RuiJiWaiMaiApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;/** 操作String类型数据=>ValueOperations:简单K-V操作* */@Testpublic void testString() {redisTemplate.opsForValue().set("city123", "shenzhen");    //  \xac\xed\x00\x05t\x00\x04city做了序列化,无法用get city获取=》config配置RedisConfigString value = (String) redisTemplate.opsForValue().get("city123");System.out.println(value);redisTemplate.opsForValue().set("key1", "value1", 10, TimeUnit.SECONDS);Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city1234", "nanjing");System.out.println(aBoolean);}/** 操作Hash类型数据=>HashOperations:针对map类型的数据操作* */@Testpublic void testHash() {HashOperations hashOperations = redisTemplate.opsForHash();hashOperations.put("002", "name", "xiaoming");hashOperations.put("002", "age", "20");String age = (String) hashOperations.get("002", "age");System.out.println(age);// 获取所有字段Set keys = hashOperations.keys("002");for (Object key : keys) {System.out.println(key);}// 获取所有值List values = hashOperations.values("002");for (Object value : values) {System.out.println(value);}}/** 操作List类型数据=>ListOperations:针对list类型的数据操作* */@Testpublic void testList() {ListOperations listOperations = redisTemplate.opsForList();//存值listOperations.leftPush("mylist", "a");listOperations.leftPushAll("mylist", "b", "c", "d");//取值List<String> mylist = listOperations.range("mylist", 0, -1);for (String value : mylist) {System.out.println(value);}//获得列表长度Long size = listOperations.size("mylist");int lSize = size.intValue();for (int i = 0; i < lSize; i++) {//出队列Object element = listOperations.rightPop("mylist");System.out.println("出队列:" + element);}}/** 操作Set(无序集合)类型数据=>SetOperations:set类型数据操作* */@Testpublic void testSet() {SetOperations setOperations = redisTemplate.opsForSet();//存值setOperations.add("myset", "a", "b", "c", "a");//取值Set<String> myset = setOperations.members("myset");for (String o : myset) {System.out.println(o);}//删除成员setOperations.remove("myset", "a", "b");myset = setOperations.members("myset");for (String o : myset) {System.out.println("删除后的数据:" + o);}}/** 操作ZSet(有序集合)类型数据=>ZSetOperations:zset类型数据操作* */@Testpublic void testZSet() {ZSetOperations zSetOperations = redisTemplate.opsForZSet();//存值zSetOperations.add("myZset", "a", 10.0);zSetOperations.add("myZset", "b", 11.0);zSetOperations.add("myZset", "c", 12.0);zSetOperations.add("myZset", "a", 13.0);//取值Set<String> myZet = zSetOperations.range("myZset", 0, -1);for (String s : myZet) {System.out.println(s);}//修改分数zSetOperations.incrementScore("myZset", "b", 20.0);myZet = zSetOperations.range("myZset", 0, -1);for (String s : myZet) {System.out.println("修改分数: " + s);}//删除成员zSetOperations.remove("myZset", "a", "b");myZet = zSetOperations.range("myZset", 0, -1);for (String s : myZet) {System.out.println("删除后的成员: " + s);}}/** 通用操作* */@Testpublic void testCommon() {//获取redis中所有的keySet keys = redisTemplate.keys("*");for (Object key : keys) {System.out.println(key);}//判断某个key是否存在Boolean itcast = redisTemplate.hasKey("itcast");System.out.println("判断某个key是否存在:"+itcast);//删除指定keyredisTemplate.delete("myZset");//获取指定key对应的value的数据类型DataType dataType = redisTemplate.type("001");System.out.println("获取指定key对应的value的数据类型:"+dataType.name());}
}

在这里插入图片描述

三、Spring Cache

【1】常用注解:
注解说明
@EnableCaching开启缓存注解功能
@Cacheable判断是否有缓存数据,有=》返回缓存数据;没有=》放到缓存中
@CachePut将方法的返回值放到缓存中
@CacheEvict将一条或多条数据从缓存中删除
【2】使用案例
package com.itheima.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.entity.User;
import com.itheima.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate CacheManager cacheManager;@Autowiredprivate UserService userService;/*** CachePut:将方法返回值放入缓存* value:缓存的名称,每个缓存名称下面可以有多个key* key:缓存的key*/@CachePut(value = "userCache",key = "#user.id")@PostMappingpublic User save(User user){userService.save(user);return user;}/*** CacheEvict:清理指定缓存* value:缓存的名称,每个缓存名称下面可以有多个key* key:缓存的key*/@CacheEvict(value = "userCache",key = "#p0")//@CacheEvict(value = "userCache",key = "#root.args[0]")//@CacheEvict(value = "userCache",key = "#id")@DeleteMapping("/{id}")public void delete(@PathVariable Long id){userService.removeById(id);}//@CacheEvict(value = "userCache",key = "#p0.id")//@CacheEvict(value = "userCache",key = "#user.id")//@CacheEvict(value = "userCache",key = "#root.args[0].id")@CacheEvict(value = "userCache",key = "#result.id")@PutMappingpublic User update(User user){userService.updateById(user);return user;}/*** Cacheable:在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中* value:缓存的名称,每个缓存名称下面可以有多个key* key:缓存的key* condition:条件,满足条件时才缓存数据* unless:满足条件则不缓存*/@Cacheable(value = "userCache",key = "#id",unless = "#result == null")@GetMapping("/{id}")public User getById(@PathVariable Long id){User user = userService.getById(id);return user;}@Cacheable(value = "userCache",key = "#user.id + '_' + #user.name")@GetMapping("/list")public List<User> list(User user){LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(user.getId() != null,User::getId,user.getId());queryWrapper.eq(user.getName() != null,User::getName,user.getName());List<User> list = userService.list(queryWrapper);return list;}
}
【3】底层不使用redis,重启服务,内存丢失=>解决:
pom.xml
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
application.yml

在这里插入图片描述

  redis:    #redis配置host: 192.168.139.128port: 6379#password:database: 0   #默认提供16个数据库,0;0号数据库cache:redis:time-to-live: 1800000 #设置缓存数据的过期时间
启动类:

在这里插入图片描述

Result:

在这里插入图片描述

注解使用:
    @PostMapping()@CacheEvict(value = "setmealCache",allEntries = true)public Result<String> save(@RequestBody SetmealDto setmealDto) {log.info("套餐信息:{}", setmealDto);setmealService.saveWithDish(setmealDto);return null;}//删除套餐@DeleteMapping()@CacheEvict(value = "setmealCache",allEntries = true)//清除setmealCache下的所有缓存public Result<String> delete(@RequestParam List<Long> ids){setmealService.removeWithDish(ids);return Result.success("套餐数据删除成功");}/*** 根据条件查询套餐数据* @param setmeal* @return*/@GetMapping("/list")@Cacheable(value = "setmealCache",key = "#setmeal.categoryId + '_' + #setmeal.status")public Result<List<Setmeal>> list(Setmeal setmeal){LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(setmeal.getCategoryId() != null,Setmeal::getCategoryId,setmeal.getCategoryId());queryWrapper.eq(setmeal.getStatus() != null,Setmeal::getStatus,setmeal.getStatus());queryWrapper.orderByDesc(Setmeal::getUpdateTime);List<Setmeal> list = setmealService.list(queryWrapper);return Result.success(list);}

相关文章:

【spring boot】在Java中操作缓存:

文章目录一、Jedis二、Spring Data Redis&#xff08;常用&#xff09;【1】pom.xml【2】application.yml【3】RedisConfig【4】RuiJiWaiMaiApplicationTests三、Spring Cache【1】常用注解&#xff1a;【2】使用案例【3】底层不使用redis&#xff0c;重启服务&#xff0c;内存…...

擂台赛-安全攻防之使用openssh后门获取root密码实战

前言 大家好&#xff0c;我是沐风晓月&#xff0c;我们开始组队学习了&#xff0c;介绍下我们的情况&#xff1a; 这几天跟队员 迎月&#xff0c;虹月&#xff0c;心月&#xff0c;古月打擂台&#xff0c;我和心月一组&#xff0c;相互攻占对方服务器。 终于在今早凌晨三点拿…...

关于React入门基础从哪学起?

文章目录前言一、React简介1. React是什么2. react 与 vue 最大的区别就是:3. React特点4. React介绍描述5. React高效的原因6.React强大之处二、React基础格式1.什么是虚拟dom&#xff1f;2.为什么要创建虚拟dom&#xff1f;三、React也分为俩种创建方式1. 使用js的方式来创建…...

python玄阶斗技--tkinter库

目录 一.tkinter库介绍 二.功能实现 1.窗口创建 2.Button 按钮 3.Entry 文本输入域 4.text 文本框 5.Listbox 多选下拉框 6.Radiobutton 多选项按钮 7.Checkbutton 多选按钮 8.Scale 滑块(拉动条) 9.Scroolbar 滚动条 10.Menu 菜单栏 11. messagebox 消息框 12…...

【MySQL】MySQL的介绍MySQL数据库及MySQL表的基本操作

文章目录数据库的介绍什么是数据库数据库分类MySQL的介绍数据库的基本操作数据库的操作创建数据库查看所有数据库选中指定的数据库删除数据库常用数据类型数值类型字符串类型日期类型表的操作创建表查看指定数据库下的所有表查看指定表的结构删除表小练习数据库的介绍 什么是数…...

【每日随笔】社会上层与中层的博弈 ( 技术无关、没事别点进来看 | 社会上层 | 上层与中层的保护层 | 推荐学习的知识 )

文章目录一、社会上层二、上层与中层的保护层三、推荐学习的知识一、社会上层 社会上层 掌握着 生产资料 和 权利 ; 社会中层 是 小企业主 和 中产打工人 ; 上层 名额有限 生产资料所有者 : 垄断巨头 , 独角兽 , 大型企业主 , 大型企业股东 , 数量有限 ;权利所有者 : 高级别的…...

Cookie 和 Session的区别

文章目录时间&#xff1a;2023年3月23日第一&#xff1a;什么是 Cookie 和 Session ?什么是 Cookie什么是 Session第二&#xff1a;Cookie 和 Session 有什么不同&#xff1f;第三&#xff1a;为什么需要 Cookie 和 Session&#xff0c;他们有什么关联&#xff1f;第四&#x…...

leetcode使用vscode调试C++代码

leetcode使用vscode调试C代码 这里记录一下大体思路吧&#xff0c;关于细节配置放上别的博主的链接&#xff0c;他们讲的更好 vscode只是编辑器&#xff0c;相当于记事本&#xff0c;需要下载minGW提供的编译器和调试器 官方介绍&#xff1a; C/C拓展不包括编译器或调试器&…...

树莓派Linux源码配置,树莓派Linux内核编译,树莓派Linux内核更换

目录 一 树莓派Linux的源码配置 ① 内核源码下载说明 ② 三种方法配置源码 二 树莓派Linux内核编译 ① 内核编译 ② 编译时报错及解决方案&#xff08;亲测&#xff09; 三 更换树莓派Linux内核 操作步骤说明 ● dmesg报错及解决方案&#xff08;亲测&#xff0…...

【C语言】深度讲解 atoi函数 使用方法与模拟实现

文章目录atoi使用方法&#xff1a;atoi模拟实现atoi 功能&#xff1a;转化字符串到整数 头文件&#xff1a; #include <stdlib.h> int atoi (const char * str); 参数 str&#xff1a;要转换为整数的字符串 返回值 如果转换成功&#xff0c;函数将转换后的整数作为int值…...

HTTPS的加密流程

1、概念HTTPS 是一个应用层协议&#xff0c;是在 HTTP 协议的基础上引入了一个加密层。HTTP 协议内容都是按照文本的方式明文传输的&#xff0c;这就导致在传输过程中出现一些被篡改的情况。HTTP协议传输的数据都是未加密的&#xff0c;也就是明文的&#xff0c;因此使用HTTP协…...

STM32配置读取BMP280气压传感器数据

STM32配置读取BMP280气压传感器数据 BMP280是在BMP180基础上增强的绝对气压传感器&#xff0c;在飞控领域的高度识别方面应用也比较多。 BMP280和BMP180的区别&#xff1a; 市面上也有一些模块&#xff1a; 这里介绍STM32芯片和BMP280的连接和数据读取。 电路连接 BMP28…...

【Linux】 基础IO——文件(中)

文章目录1. 文件描述符为什么从3开始使用&#xff1f;2. 文件描述符本质理解3. 如何理解Linux下的一切皆文件&#xff1f;4. FILE是什么&#xff0c;谁提供&#xff1f;和内核的struct有关系么&#xff1f;证明struct FILE结构体中存在文件描述符fd5. 重定向的本质输出重定向输…...

蓝桥杯刷题冲刺 | 倒计时13天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.母牛的故事2.魔板1.母牛的故事 题目 链接&#xff1a; [递归]母牛的故事 - C语言网 (dotcpp.c…...

MIPI D-PHYv2.5笔记(5) -- 不同的PHY配置方式

声明&#xff1a;作者是做嵌入式软件开发的&#xff0c;并非专业的硬件设计人员&#xff0c;笔记内容根据自己的经验和对协议的理解输出&#xff0c;肯定存在有些理解和翻译不到位的地方&#xff0c;有疑问请参考原始规范看 规范5.7章节列举了一些常见的PHY配置&#xff0c;但实…...

【周末闲谈】文心一言,模仿还是超越?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 周末闲谈 ✨第一周 二进制VS三进制 文章目录周末闲谈前言一、背景环境二、文心一言&#xff1f;(_)?三、文心一言的优势&#xff1f;&#x1f617;&#x1f617;&#x1f617;四、文心一…...

《一“企”谈》 | 「佛山市政」:携手企企通,让采购业务数智化

近日&#xff0c;国家施工总承包壹级企业「佛山市市政建设工程有限公司」&#xff08;以下简称“佛山市政”&#xff09;正积极布局数字化建设工作&#xff0c;基于采购业务数智化&#xff0c;携手企企通打造了SaaS采购云平台。 01、岭南建筑强企 匠心铸造精品 …...

Spark运行架构

目录 1 运行架构 2 核心组件 2.1 Driver 2.2 Executor 2.3 Master & Worker 2.4 ApplicationMaster 3 核心概念 3.1 Executor 与 Core 3.2 并行度&#xff08; Parallelism&#xff09; 3.3 ​​​​​​​有向无环图&#xff08; DAG&#xff09; 4 提交流程 …...

基于卷积神经网络CNN的水果分类预测,卷积神经网络水果等级识别

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN水果分类预测 基本结构 主要参数 MATALB代码 结果图 展望 背影 现在生活&#xff0c;为节能减排&#xff0c;减少电能…...

Spring Boot 框架总结

Spring Boot 框架总结 1. springboot的引言 Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化Spring应用的 初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不 再需要定义样板化的配置。通过这种方式&#xff0…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...