2023.1.13 关于在 Spring 中操作 Redis 服务器

目录

引言

前置工作

前置知识

实例演示

String 类型

List 类型

Set 类型

Hash 类型

ZSet 类型


引言

  • 进行下述操作的前提是 你的云服务器已经配置好了 ssh 端口转发
  • 即已经将云服务器的 Redis 端口映射到本地主机

注意:

  • 此处我们配置的端口号为 8888

可点击下方链接了解如何配置 ssh 端口转发 

Java 客户端连接 Redis 服务器

前置工作

1、在 SpringBoot 项目的 pom.xml 文件中添加依赖

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

2、编写 application.yml 配置文件

spring:redis:host: 127.0.0.1port: 8888

前置知识

  • 相较于使用 Jedis 库通过 Jedis 对象里的各种方法来操作 Redis 
  • 此处 Spring 则是通过 StringRedistemplate 来操作 Redis 

注意:

  • StringRedistemplate 类提供的方法相较于 Jedis 对象里的各种方法,具有较大差异

  • StringRedistemplate 类将操作 Redis 的方法分成了几个类别,分门别类的来进行组织
  • 即做了进一步的封装!
  • 所以此处提供的一些接口风格和原生 Redis 命令就有一定的差异了
  • 首先其初心是希望通过上述重新的封装,让接口用起来更简单
  • 在我看来其初心并未达成,反而因为和 Redis 原生命令的差异,提高了使用者学习成本

补充:

  • Spring 最原始提供的类是 RedisTemplate
  • StringRedistemplate 类是 RedisTemplate 的子类 专门用来处理 文本数据的

  • 但是 Redistemplate 类留了一个后手,让我们随时能够执行到 Redis 原生的命令
  • 即通过 execute 方法

实例理解

  • 此处我们想要在 Redis 中执行 FLUSHALL 命令
stringRedisTemplate.execute((RedisConnection connection) -> {
//    execute 要求回调方法中必须写 return 语句,返回个东西
//    这个回调返回的对象,就会作为 execute 本身的返回值connection.flushAll();return null;
});

  • 函数式接口,相当于一个回调函数
  • 就在回调里,写咱们要执行的 redis 命令
  • 这个回调就会被 RedisTemplate 内部进行执行

补充:

  • 当我们点击查看 RedisCallback<T> 的源码

  • 此处的 RedisConnection 就代表了 Redis 链接,对标 Jedis 对象

实例演示

  • 此处 Redis 测试的各种方法,均通过 Controller 提供的 HTTP 接口来触发的
  • 即我们可先创建一个 MyController 类,并在该类中进行测试代码的编写
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.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.util.Set;@RestController
public class MyController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;//   ...
}

String 类型

    @GetMapping("/testString")@ResponseBodypublic String testString() {
//        先清除之前的数据stringRedisTemplate.execute((RedisConnection connection) -> {connection.flushAll();return null;});stringRedisTemplate.opsForValue().set("key","111");stringRedisTemplate.opsForValue().set("key2","222");stringRedisTemplate.opsForValue().set("key3","333");String value = stringRedisTemplate.opsForValue().get("key");System.out.println("value = " + value);return "OK";
}

运行结果:


List 类型

    @GetMapping("/testList")@ResponseBodypublic String testList() {
//        先清除之前的数据stringRedisTemplate.execute((RedisConnection connection) -> {
//            execute 要求回调方法中必须写 return 语句,返回个东西
//            这个回调返回的对象,就会作为 execute 本身的返回值connection.flushAll();return null;});stringRedisTemplate.opsForList().leftPush("key","111");stringRedisTemplate.opsForList().leftPush("key","222");stringRedisTemplate.opsForList().leftPush("key","333");String value = stringRedisTemplate.opsForList().rightPop("key");System.out.println("value = " + value);value = stringRedisTemplate.opsForList().rightPop("key");System.out.println("value = " + value);value = stringRedisTemplate.opsForList().rightPop("key");System.out.println("value = " + value);return "OK";}

运行结果:


Set 类型

    @GetMapping("/testSet")@ResponseBodypublic String testSet() {
//        先清除之前的数据stringRedisTemplate.execute((RedisConnection connection) -> {
//            execute 要求回调方法中必须写 return 语句,返回个东西
//            这个回调返回的对象,就会作为 execute 本身的返回值connection.flushAll();return null;});stringRedisTemplate.opsForSet().add("key","111","222","333");Set<String> result = stringRedisTemplate.opsForSet().members("key");System.out.println("result = " + result);Boolean exists = stringRedisTemplate.opsForSet().isMember("key","111");System.out.println("exists = " + exists);Long count = stringRedisTemplate.opsForSet().size("key");System.out.println("count = " + count);stringRedisTemplate.opsForSet().remove("key","111","222");result = stringRedisTemplate.opsForSet().members("key");System.out.println("result = " + result);return "OK";}

运行结果:


Hash 类型

    @GetMapping("/testHash")@ResponseBodypublic String testHash() {
//        先清除之前的数据stringRedisTemplate.execute((RedisConnection connection) -> {
//            execute 要求回调方法中必须写 return 语句,返回个东西
//            这个回调返回的对象,就会作为 execute 本身的返回值connection.flushAll();return null;});stringRedisTemplate.opsForHash().put("key","f1","111");stringRedisTemplate.opsForHash().put("key","f2","222");stringRedisTemplate.opsForHash().put("key","f3","333");String value = (String) stringRedisTemplate.opsForHash().get("key","f1");System.out.println("value = " + value);Boolean exists = stringRedisTemplate.opsForHash().hasKey("key","f1");System.out.println("exists = " + exists);stringRedisTemplate.opsForHash().delete("key","f1","f2");Long size = stringRedisTemplate.opsForHash().size("key");System.out.println("size = " + size);return "OK";}

运行结果:


ZSet 类型

    @GetMapping("/testZSet")@ResponseBodypublic String testZSet() {
//        先清除之前的数据stringRedisTemplate.execute((RedisConnection connection) -> {
//            execute 要求回调方法中必须写 return 语句,返回个东西
//            这个回调返回的对象,就会作为 execute 本身的返回值connection.flushAll();return null;});stringRedisTemplate.opsForZSet().add("key","xxl",10);stringRedisTemplate.opsForZSet().add("key","wml",20);stringRedisTemplate.opsForZSet().add("key","shw",30);Set<String> members = stringRedisTemplate.opsForZSet().range("key",0,-1);System.out.println("members = " + members);Set<ZSetOperations.TypedTuple<String>> membersWithScore = stringRedisTemplate.opsForZSet().rangeWithScores("key",0,-1);System.out.println("membersWithScore = " + membersWithScore);Double score = stringRedisTemplate.opsForZSet().score("key","xxl");System.out.println("score = " + score);stringRedisTemplate.opsForZSet().remove("key","xxl");Long size = stringRedisTemplate.opsForZSet().size("key");System.out.println("size = " + size);Long rank = stringRedisTemplate.opsForZSet().rank("key","wml");System.out.println("rank = " + rank);return "OK";}

运行结果:

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

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

相关文章

jmeter如何做接口测试?

Jmeter介绍&测试准备&#xff1a; Jmeter介绍&#xff1a;Jmeter是软件行业里面比较常用的接口、性能测试工具&#xff0c;下面介绍下如何用Jmeter做接口测试以及如何用它连接MySQL数据库。 前期准备&#xff1a;测试前&#xff0c;需要安装好Jmeter以及jdk并配置好jdk环…

小知识分享2

文章目录 1.TCP/IP协议2.四次挥手断开连接3.TCP的三次握手和四次挥手4.在什么情况下需要设置WINS Proxy&#xff1f;5.用户与用户账户有什么不同&#xff1f;为什么需要使用用户账户&#xff1f; 1.TCP/IP协议 1、TCP/IP、Transmission Control Protocol/internet Protocol,传…

杨中科 EFCORE 第三部分 主键

主键 自增主键 1、EF Core支持多种主键生成策略:自动增长;Guid;Hi/Lo算法等。 2、自动增长。 优点:简单; 缺点: 数据库迁移以及分布式系统中&#xff08;多数据库合并&#xff0c;会有重复主键值&#xff09;比较麻烦;并发性能差&#xff08;大并发情况下&#xff0c;为了保证…

函数栈桢的创建和销毁

函数栈桢的创建和销毁 一、解决的问题二、认识常用的寄存器及其指令操作三、函数栈桢解析三、回答问题 一、解决的问题 1.局部变量是怎么创建的&#xff1f;  2.为什么局部变量的值是随机值&#xff1f;  3.函数是怎么传参的&#xff1f;传参的顺序是怎样的&#xff1f;  4.…

python24.1.14while循环

当条件结束时间未知时&#xff0c;while循环比for循环更合适 实践

带你拿捏SpringBoot自动装配的核心技术?模块装配(@EnableXXX注解+@Import)+ 条件装配(@ConditionalXXX)

文章目录 Profile激活指定配置文件主配置文件中指定激活的profile命令行激活设置虚拟机参数激活 profile控制不到的地方 Spring原生的条件装配注解ConditionalConditional接口讲解案例讲解 Spring Boot封装的条件装配注解ConditionalXXX自己实现ConditionalOnBeanSpringBoot 源…

自制数据库空洞率清理工具-C版-03-EasyClean-V1.2(支持南大通用数据库Gbase8a)

目录 一、环境信息 二、简述 三、升级点 四、支持功能 五、空洞率 六、工具流程图 1、流程描述 2、注意点 &#xff08;1&#xff09;方法一 &#xff08;2&#xff09;方法二 七、清理空洞率流程图 八、安装包下载地址 九、参数介绍 1、命令模板 2、命令样例 3…

【集合大练习】---------------简易学生管理系统

目标&#xff1a; 实现学生对象新增&#xff0c;删除&#xff0c;查看&#xff0c;对象信息修改 整体实现思路&#xff1a; 1.定义学生类-------------创建学生对象 2.管理界面代码编写-------------命令提示面板 3.添加学生的代码编写---------add功能实现 4.查看学生信…

4、C语言:指针与数组

数组与指针 指针与地址指针与函数参数指针与数组地址算数运算字符指针与函数指针数组以及指向指针的指针多维数组命令行参数指向函数的指针复杂声明 指针是一种保存变量地址的变量。C语言中&#xff0c;指针的使用非常广泛&#xff0c;原因之一是&#xff0c;指针常常是表达某个…

智能合约笔记

前言&#xff1a; 首先了解下为什么会出现智能合约&#xff0c;打个比方现在有两个人A和B打赌明天会不会下雨&#xff0c;每个人赌注100元&#xff0c;如果第二天下雨则A拿走200元&#xff0c;否则B拿走200元&#xff0c;这样就有一个问题&#xff0c;赌注要到第二天才能见效&…

Python 中的字符串分割函数 split() 详解

更多Python学习内容&#xff1a;ipengtao.com 在 Python 编程中&#xff0c;处理字符串是一项常见的任务。字符串分割是其中的一个常见操作&#xff0c;而 Python 提供了强大的 split() 函数&#xff0c;用于将字符串拆分成多个部分。本文将详细介绍 split() 函数的用法、参数和…

Linux 转换文字编码与换行符 nkf命令

参考资料 【 nkf 】コマンド――文字コードと改行コードを変換するnkfコマンドでファイルの文字コードと改行コードを統一する 目录 一. 前期准备二. 乱码现象与分析三. nkf命令3.1 nkf --guess 查看文件编码3.2 nkf -w8 UTF-8(BOM)编码显示3.3 nkf -wd --overwrite 覆盖源文件…

MySQL核心SQL

一.结构化查询语言 SQL是结构化查询语言&#xff08;Structure Query Language&#xff09;&#xff0c;它是关系型数据库的通用语言。 SQL 主要可以划分为以下 3 个类别&#xff1a; DDL&#xff08;Data Definition Languages&#xff09;语句 数据定义语言&#xff0c;这…

C#无标题栏窗体拖动代码

文章目录 一、概念二、案例三、常见问题四、链接 一、概念 C#&#xff08;C Sharp&#xff09;是由微软公司开发的一种面向对象的编程语言。它是从C和C语言演化而来的&#xff0c;并结合了Java和其他编程语言的特性。C#是微软.NET平台的一部分&#xff0c;允许开发人员创建各种…

EMC VNXe / Unity存储系统如何找回密码

开始之前&#xff0c;先简单说说&#xff0c;EMC的VNXe存储之间的关系。 EMC的VNXe和Unity存储的操作系统OS是一样的&#xff0c;当然不是完全一样&#xff0c;但是架构是一样的&#xff0c;先推出的产品是VNXe&#xff0c;然后在这个基础上演进到了Unity&#xff0c;Unity XT…

港大谷歌提出GO-NeRF:在NeRF中生成协调且高质量的3D对象

尽管在3D生成方面取得了进展&#xff0c;但在作为NeRF表示的现有3D场景中直接创建3D对象仍然是未经探索的。这个过程不仅需要高质量的3D对象生成&#xff0c;还需要将生成的3D内容无缝地合成到现有的NeRF中。为此&#xff0c;作者提出了一种新方法&#xff0c;GO-NeRF&#xff…

电脑定时关机应用

这是一个Python应用。家里卧室装了新电视&#xff0c;HDMI连接笔记本追剧还是很愉快的。可是经常睡着&#xff0c;自然忘了关机。搜了一大圈&#xff0c;都是用命令行或者bat解决。商店里的应用也不好用&#xff0c;有些还收费。于是萌生了自己写一个定时关机应用的想法。利用N…

监控平台zabbix介绍与部署

1. 完整的项目 业务架构&#xff1a;客户端 -> 防火墙 -> 负载均衡&#xff08;四层、七层&#xff09;-> Web缓存/应用 -> 业务逻辑&#xff08;动态应用&#xff09;-> 数据缓存 -> 数据持久 运维架构&#xff1a;运维客户端 -> 堡垒机/跳板机&#x…

TLC Nand Flash 存储单元的读取原理

我们知道Nand Flash使用浮栅晶体管作为存储单元&#xff08;memory cell&#xff09;来存储数据&#xff0c;浮栅晶体管物理结构如图1所示&#xff1a; 图1 浮栅晶体管 对于普通的晶体管&#xff08;去掉浮栅晶体管中的浮栅层&#xff0c;floating gate&#xff09;&#xff0…

基于Docker的Nginx的安装与配置

基于Docker的Nginx的安装与配置 1 为Nginx创建一个容器1.1 学习docker run1.2 通过docker run为Nginx创建并启动一个容器 2 配置Nginx2.1 学习docker的bind mount技术2.2 在Nginx容器中找到想修改的文件所在的目录2.2.1 认识nginx.conf文件2.2.2 访问Nginx服务&#xff0c;默认…