Spring 框架下 Redis 数据结构的全面解析

news2024/11/15 7:22:34

Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 本篇文章给大家带来的是如何通过 Spring 来操作 Redis 中的常见数据结构 , 以及如何通过代码执行 Redis 中的原生命令 .

在这里插入图片描述

本专栏旨在为初学者提供一个全面的 Redis 学习路径,从基础概念到实际应用,帮助读者快速掌握 Redis 的使用和管理技巧。通过本专栏的学习,能够构建坚实的 Redis 知识基础,并能够在实际学习以及工作中灵活运用 Redis 解决问题 .
专栏地址 : Redis 入门实践

一 . 前置操作

1.1 创建项目

我们先来创建一个 Spring Boot 的项目
image.png
image.png
image.png
image.png
然后更改一下配置文件的格式
image.png
image.png

1.2 设置 Redis 的连接信息

在 application.yml 中粘贴下面的代码

spring:
  redis:
    host: 127.0.0.1
    port: 8888

1.3 设置项目分层结构

image.png
image.png
然后在类上面添加 @RestController 注解
那后续我们测试 Redis 的各种方法 , 就通过 Spring Web 中的接口方法来去触发

1.4 注入 Redis

我们要想使用 Redis , 就需要将 Redis 注入到我们的 TestController 中
image.png

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;
}

二 . string 类型

我们通过访问对应的路由 , 来去触发 Redis 的各种操作
image.png

我们只是简单的介绍一下 set 和 get 命令 , 其他命令虽然说跟 Jedis 有一些差别 , 但是仍然可以通过 IDEA 的选项选择出我们需要的方法 , 再按照它的参数要求去编写对应的方法即可
image.png
我们使用 redisTemplate 的时候 , 发现并没有 set / get 相关方法了
这是因为 RedisTemplate 做了进一步的封装
image.png
我们给每个类型设计了不同的对象 , 所以需要我们调用不同的类型来去使用 , 这就跟我们原生的 Jedis 就有一些差异了
我们就可以通过 redisTemplate.opsForValue() 来去操作 string 类型了
image.png

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/testString")
    public String testString() {
        // 设置键值对
        redisTemplate.opsForValue().set("k1", "111");
        redisTemplate.opsForValue().set("k2", "222");
        redisTemplate.opsForValue().set("k3", "333");

        // 获取键值对
        String value = redisTemplate.opsForValue().get("k1");
        System.out.println("value = " + value);

        return value;
    }
}

然后我们访问 http://127.0.0.1:8080/testString 就可以在控制台看到我们的信息了
image.png

三 . list 类型

我们刚才插入了一些数据 , 那我们要清空一下数据库 .
image.png
但是这并没有 flushdb 这个方法啊 , 而且看了一圈也没提供 flushdb 这个方法啊 .
那 Spring 就提供给我们一个执行原生命令的方法
image.png
那参数里面的 RedisCallback action 就相当于一个回调函数 , 在这个回调函数中写下我们需要执行的 Redis 命令 , 那这个回调函数就会被 RedisTemplate 内部进行执行
我们再来具体看一下 execute 这个方法
image.png
image.png
image.png
image.png
那 RedisConnection 就代表了 Redis 的连接 (就跟 Jedis 对象类似)
那我们也应该传入一个 Redis 连接 , 我们使用 lambda 的方式
现在 execute 的方法中编写一个 lambda 表达式
image.png
然后在 () 中创建 Redis 连接 , 在 {} 中编写要执行的 Redis 语句
image.png
那目前 execute 这个方法还在报错 , 是因为回调函数需要我们返回一个返回值 , 而我们只是清空一下数据库 , 并不需要返回什么 , 所以直接返回一个 null 即可
image.png
然后我们就可以模拟列表的各个方法了

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/testList")
    public String testList() {
        // 清空数据库
        // 避免上一组的测试数据影响到下一组的测试结果
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushDb();
            return null;
        });

        // 向列表中添加数据
        // 头插法
        redisTemplate.opsForList().leftPush("key", "111");
        // 尾插法
        redisTemplate.opsForList().rightPush("key", "222");
        redisTemplate.opsForList().rightPush("key", "333");
        redisTemplate.opsForList().rightPush("key", "444");

        // 获取列表中的元素
        List<String> result = redisTemplate.opsForList().range("key", 0, -1);
        System.out.println("result = " + result);

        // 删除操作
        // 头删法
        String value1 = redisTemplate.opsForList().leftPop("key");
        System.out.println("头删法 : " + value1);
        // 尾删法
        String value2 = redisTemplate.opsForList().rightPop("key");
        System.out.println("尾删法 : " + value2);
        return "OK";
    }
}

image.png

四 . set 类型

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/testSet")
    public String testSet() {
        System.out.println("测试 集合 类型");

        // 清空数据库
        // 避免上一组的测试数据影响到下一组的测试结果
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushDb();
            return null;
        });

        // 向集合中添加元素
        redisTemplate.opsForSet().add("key", "111", "222", "333", "444");

        // 获取集合中的元素
        Set<String> result = redisTemplate.opsForSet().members("key");
        System.out.println("集合当中的元素 : " + result);

        // 判断元素是否在集合中
        Boolean exists = redisTemplate.opsForSet().isMember("key", "111");
        System.out.println("该元素是否存在 : " + exists);

        // 获取集合的元素个数
        Long len = redisTemplate.opsForSet().size("key");
        System.out.println("集合的元素个数为 : " + len);

        // 删除元素
        Long delNum = redisTemplate.opsForSet().remove("key", "111", "222");
        System.out.println("删除的元素个数为 : " + delNum);

        return "OK";
    }
}

image.png

五 . hash 类型

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/testHash")
    public String testHash() {
        System.out.println("测试 哈希 类型");

        // 清空数据库
        // 避免上一组的测试数据影响到下一组的测试结果
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushDb();
            return null;
        });

        // 添加元素
        redisTemplate.opsForHash().put("k1", "f1", "111");
        redisTemplate.opsForHash().put("k1", "f2", "222");
        redisTemplate.opsForHash().put("k1", "f3", "333");
        redisTemplate.opsForHash().put("k1", "f4", "444");

        // 获取元素
        String value = (String) redisTemplate.opsForHash().get("k1", "f1");
        System.out.println("value = " + value);

        // 判断是否存在
        Boolean isExists = redisTemplate.opsForHash().hasKey("k1", "f1");
        System.out.println("该元素是否存在 : " + isExists);

        // 获取哈希个数
        Long size = redisTemplate.opsForHash().size("k1");
        System.out.println("集合的元素个数为 : " + size);

        // 删除元素
        redisTemplate.opsForHash().delete("key", "f1", "f2");
        
        return "OK";
    }
}

image.png
要注意的是 , 我们在调用 get 方法的时候
image.png
所以我们需要进行强转

六 . zset 类型

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;

@RestController
public class TestController {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping("/testZSet")
    public String testZSet() {
        System.out.println("测试 zset 类型");

        // 清空数据库
        // 避免上一组的测试数据影响到下一组的测试结果
        redisTemplate.execute((RedisConnection connection) -> {
            connection.flushDb();
            return null;
        });

        // 添加元素
        // 注意: 这里的顺序是先 value 再 score
        redisTemplate.opsForZSet().add("key", "zhangsan", 10.0);
        redisTemplate.opsForZSet().add("key", "lisi", 20.0);
        redisTemplate.opsForZSet().add("key", "wangwu", 30.0);

        // 获取所有元素
        Set<String> result1 = redisTemplate.opsForZSet().range("key", 0, -1);// 只获取所有的 members
        Set<ZSetOperations.TypedTuple<String>> result2 = redisTemplate.opsForZSet().rangeWithScores("key", 0, -1);// 既获取 members, 又获取 scores
        System.out.println("所有的成员 : " + result1);
        System.out.println("成员 + 成绩 : " + result2);

        // 查询某个成员的成绩
        Double score = redisTemplate.opsForZSet().score("key", "zhangsan");
        System.out.println("zhangsan 的成绩为 : " + score);

        // 获取有序集合元素个数
        Long len = redisTemplate.opsForZSet().size("key");
        System.out.println("有序集合的元素个数为 : " + len);

        // 返回指定元素所在成绩排名
        Long rank = redisTemplate.opsForZSet().rank("key", "zhangsan");
        System.out.println("该元素成绩所在排名 " + rank);
        
        // 删除元素
        redisTemplate.opsForZSet().remove("key", "zhangsan");
        
        return "OK";
    }
}

image.png
其中 , 要注意的操作是 rangeWithScores 这个方法
我们注意一下他的返回值
image.png
Tuple 很眼熟 , 我们在 Jedis 中介绍过了 , 他是一个元组 , 更通俗来说就是一组打包好的数据 .
那我们只需要按照源码提示我们的方式 , 替换掉泛型即可
image.png


那通过这些简单的命令 , 我们就简单的了解了怎样通过 Spring 来去操作 Redis .
虽然我们并未针对每个数据结构的命令进行详细介绍 , 但是其他方法我们通过 IDEA 的提示也能编写出对应的方法
我们也可以通过 Spring 官网提供的教程来去进行查阅 : https://spring.io/projects/spring-data-redis/

那如果对你产生帮助的话 , 还请一键三连 , 感谢 ~
在这里插入图片描述

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

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

相关文章

【C++题解】1088 - 求两个数M和N的最大公约数

问题四&#xff1a;1088 - 求两个数M和N的最大公约数 类型&#xff1a;需要找规律的循环。 题目描述&#xff1a; 求两个正整整数 M 和 N 的最大公约数(M&#xff0c;N都在长整型范围内&#xff09; 输入&#xff1a; 输入一行&#xff0c;包括两个正整数。 输出&#xff…

Antv a-table 表格行/列合并,在合并后的td中使用插槽slot

【需求】 这次的表格需要实现行列合并&#xff0c;并且要在合并后的 td 中使用子组件或弹出弹窗&#xff0c;难点在于&#xff1a; 1. 根据提供的data&#xff0c;自行判断是否合并项的 getRowspan方法 2. customCell 、scopedSlots 冲突导致的子组件无法展示 &#xff08…

Cesium 实战 - 自定义纹理材质 - 流动线(精灵线)

Cesium 实战 - 自定义纹理材质 - 流动线(精灵线) 核心代码完整代码在线示例Cesium 给实体对象(Entity)提供了很多实用的样式,基本满足普通项目需求; 但是作为 WebGL 引擎,肯定不够丰富,尤其是动态效果样式。 对于实体对象(Entity),可以通过自定义材质,实现各种动…

【YOLOv8系列】YOLOv8的GUI界面设计;在电脑本地实现YOLOv8的可视化交互界面设计(对摄像头的实时画面进行分类)

背景: 最近在研究YOLOv8的应用,并且已经在自己的笔记本环境中跑通了YOLOv8的检测和分类算法,训练、验证、预测等功能均已实现;也通过自己的数据集训练出了自己的模型(权重);且之前也做了一个webUI界面,对YOLOv8检测和分类的结果进行展示;但是如果在本地的GUI界面调用摄…

Python pip 更换镜像源

文章目录 1 概述1.1 默认镜像&#xff0c;速度慢&#xff0c;易报错1.2 常用国内镜像源 2 更改镜像源2.1 临时更改2.2 永久更改2.2.1 查看配置源及配置文件2.2.2 编辑 pip.ini2.2.3 配置后的效果 1 概述 1.1 默认镜像&#xff0c;速度慢&#xff0c;易报错 默认镜像&#xff…

导出硬盘所有文件名到txt文本文件——C#学习笔记

下面的示例演示如何使用递归遍历目录树。递归方法很简洁&#xff0c;但如果目录树很大且嵌套很深&#xff0c;则有可能会引起堆栈溢出异常。 对于所处理的特定异常以及在每个文件和文件夹上执行的特定操作&#xff0c;都只是作为示例提供。您应该修改此代码来满足自己特定的需…

分类学习器(Classification Learner App)MATLAB

在MATLAB中&#xff0c;分类学习器用于构建和评估分类模型。MATLAB提供了一些工具和功能&#xff0c;帮助你进行分类任务&#xff0c;例如分类学习器应用程序、统计和机器学习工具箱中的函数等。 导入数据 我们在打开应用程序之前的第一步将是导入我们将在工作区使用的数据。…

新品上市丨科学级新款制冷相机sM4040A/sM4040B

sM4040B科学级显微制冷相机 特性 sM4040B搭载了 GSENSE4040BSI 3.2 英寸图像传感器&#xff0c;针对传感器固有的热噪声&#xff0c;专门设计了高效制冷模块&#xff0c;使得相机传感器的工作温度比环境温度低达 35-40 度。针对制冷相机常见的低温结雾现象设计了防结雾机制&a…

Serverless 应用引擎 SAE 助力袋拉拉研发提效 70%

作者&#xff1a;百潼 医院环保 IOT 设备的引领者&#xff1a;机汽猫 机汽猫是⼀家致⼒于通过投放⾃助取袋设备&#xff0c;为医院场景提供新型环保袋交付⽅式的科技公司。它成⽴于 2019 年&#xff0c;旗下品牌袋拉拉&#xff08;DaiLala&#xff09;通过投放⾃助取袋机&…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 10数据中心中的BGP

本章解答以下问题&#xff1a; ASN&#xff0c;团体&#xff08;community&#xff09;&#xff0c;属性&#xff08;attribute&#xff09;&#xff0c;最佳路径这些BGP术语是什么疑似&#xff1f;在数据中心中应该使用eBGP还是iBGP?在数据中心使用BGP时&#xff0c;应采用什…

序列化和反序列化之Serializable与Parcelable的异同

目录 序列化和反序列化Serializable 和 Parcelable 的区别Serializable特点Parcelable特点Serializable、Parcelable 使用场景区别总结 在 Android 开发中&#xff0c;序列化和反序列化是将对象转换为字节流以及从字节流还原对象的过程。Java 提供了 Serializable 接口&#xf…

jmeter中响应时间、TPS、服务器资源图表

一、响应时间图表 jmeter中的聚合报告已经足够显示响应时间&#xff0c;但是不会显示很详细&#xff0c;下面使用监听器中的插件查看&#xff0c; 添加后&#xff0c;可以不用更改任何配置&#xff0c;直接使用默认即可统计响应时间 还是抓取百度1分钟查看数据&#xff0c;也是…

Meta:大语言模型可以通过自我批判取得大幅提升!

夕小瑶科技说 原创 作者 | 谢年年 论文的审稿模式想必大家都不会陌生&#xff0c;一篇论文除了分配多个评审&#xff0c;最后还将由PC综合评估各位审稿人的reviews撰写meta-review。 最近&#xff0c;来自Meta的研究团队将这一模式引进到大模型的对齐训练中。模型同时扮演 执…

一. 从Hive开始

1. 怎么理解Hive Hive不能理解成一个传统意义上的数据库&#xff0c;应该理解成一个解决方案。 是Hadoop在hdfs和mapreduce之后才出现的一个结构化数据处理的解决方案。 Hdfs解决了大数据的存储问题&#xff0c;mapreduce解决了数据的计算问题。 一切似乎很美好。 但是使用成本…

人机环境系统智能与Petri网

人机环境系统工程是一门新兴的交叉学科&#xff0c;它以人、机、环境为系统&#xff0c;研究系统整体的优化。而 Petri 网是一种用于描述和分析系统动态行为的图形化建模工具。 在人机环境系统中&#xff0c;智能体现在人、机、环境三个要素之间的相互作用和协同工作。人的智能…

【微信小程序】搭建项目步骤 + 引入Tdesign UI

目录 创建1个空文件夹&#xff0c;选择下图基础模板 开启/支持sass 创建公共style文件并引入 引入Tdesign UI: 1. 初始化&#xff1a; 2. 安装后&#xff0c;开发工具进行构建&#xff1a; 3. 修改 app.json 4. 使用 5. 自定义主题色 创建1个空文件夹&#xff0c;选择下…

map和set的使用和底层实现

嗨喽大家好&#xff0c;时隔许久阿鑫又给大家带来了新的博客&#xff0c;c进阶——map和set的使用和底层实现&#xff0c;下面让我们开始今天的学习吧&#xff01; map和set的使用和底层实现 1.set和multiset的使用 2.map和multimap的使用 3.底层结构 1.set和multiset的使…

基于FCM模糊聚类算法的图像分割matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 FCM算法原理 4.2 图像分割中的应用 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包…

单列表集合顶层接口Collection

List&#xff1a;添加元素是有序&#xff0c;可重复&#xff0c;有索引 Set&#xff1a;添加元素是无序&#xff0c;不重复&#xff0c;无索引 Collection是单列集合的祖宗接口&#xff0c;它的功能是全部单列集合都可以继承使用。 1.添加元素 细节1:如果我们要往List系列集…

ArcGIS出图格网小数位数设置

1、比如要去掉格网后面的小数点&#xff0c;如何设置呢&#xff1f; 2、如下图设置。