上篇文章:

Redis数据类型之zsethttps://blog.csdn.net/sniper_fandc/article/details/149139955?fromshare=blogdetail&sharetype=blogdetail&sharerId=149139955&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

目录

1 Redis客户端和服务器使用自定义协议

2 Java集成Redis

2.1 端口开放

2.2 依赖引入

2.3 测试连接

2.4 set和get测试

2.5 exists和del测试

2.6 keys测试

2.7 expire和ttl测试

2.8 type测试

3 SpringBoot集成Redis

3.1 配置文件

3.2 使用方法

3.2.1 引入依赖

3.2.2 注入Bean

3.2.3 使用redis


1 Redis客户端和服务器使用自定义协议

        Redis客户端和服务器使用自定义协议(应用层)进行网络通信,即RESP协议。

        RESP协议是基于序列化的协议,传输的数据以字符串格式组织。优点是:1.简单好实现。2.快速进行解析。3.肉眼可读。

        该协议的传输层协议是TCP,但是只使用了TCP协议的连接操作,其他的没再使用。请求和响应之间采用:一问一答的形式。请求发送客户端的Redis命令的bulk strings数组,响应返回的类型不同,根据不同Redis命令的实现返回不同类型的响应(OK、整数、数组等等)。

        对于请求和响应的数据的字符串有5种类型:

        (1)Simple Strings:以+开头的字符串,只能传输简单的文本,不能传输二进制安全的数据。

        (2)Errors:以-开头的字符串。

        (3)Integers:以:开头的字符串。

        (4)Bulk Strings:以$开头的字符串,能传输二进制安全的数据。

        (5)Arrays:以*开头的字符串。

2 Java集成Redis

2.1 端口开放

        使用Java访问Redis如果采用本地方式访问,即Java程序和Redis服务器在一台主机上,通过127.0.0.1:6379即可访问。但是Java客户端如果想要跨主机访问Redis客户端,就必须通过公网IP来访问,这就会把Redis的端口6379暴露在公网中,很容易遭受黑客入侵。

        解决办法是使用ssh协议,配置ssh端口转发,把远程Redis服务器的端口号映射到本地主机。ssh协议通常用于Windows与Linux系统网络交互,默认端口号22,由于ssh协议是加密的网络传输协议,安全程度很高,因此可以构造ssh请求包,把希望访问Redis端口号6379构造成ssh请求包的数据,通过22端口传输到Linux服务器,再由Linux服务器的ssh协议解析请求。

        由于可能有多个客户端想要跨主机访问Linux服务器的其他服务器的端口号,ssh为了区分这些端口号,就会把Linux的各种服务的端口号映射到本地主机(发出访问请求的主机)的其他端口号(比如Linux的Redis端口6379映射到本地主机8888端口),从而达到客户端访问本地端口即可实现访问Redis端口,这就是ssh的端口转发功能。客户端访问本地端口,其余的事情都有ssh来完成(数据通过ssh协议的加密通道完成传输)。

        这里使用FinalShell终端连接工具,其他终端连接工具都有类似的界面:

        选择新建隧道,配置ip和端口号,这里类型是本地,没有用到跨主机连接(远程类型)。目标地址是Redis服务器的地址,即Linux的地址。监听端口表示Redis端口映射到本地的端口是8888:

        8888端口出现监听状态,说明配置成功。

2.2 依赖引入

        <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.2</version></dependency>

2.3 测试连接

    public void testRedis(){JedisPool jedisPool = new JedisPool("tcp://127.0.0.1:8888");try(Jedis jedis = jedisPool.getResource()){String pong = jedis.ping();System.out.println("收到来自Redis服务器的响应:" + pong);}}

        由于配置了ssh端口转发,因此这里访问本机的8888端口即可访问Redis的服务器。

2.4 set和get测试

    public void testSetAndGet(){try(Jedis jedis = jedisPool.getResource()){SetParams setParams = new SetParams();setParams.px(10);jedis.set("javatest","1");String result = jedis.get("javatest");System.out.println("javatest:" + result);}}

2.5 exists和del测试

    public void existanddel(){try(Jedis jedis = jedisPool.getResource()){jedis.set("javatest","1");Boolean result = jedis.exists("javatest");System.out.println("javatest是否存在?" + result);Long delResult = jedis.del("javatest","javatest2");System.out.println("删除元素个数:" + delResult);result = jedis.exists("javatest");System.out.println("javatest是否存在?" + result);}}

2.6 keys测试

    public void keys(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("javatest","1");jedis.set("javatest2","2");Set<String> result = jedis.keys("*");System.out.println(result.toString());}}

2.7 expire和ttl测试

    public void expireAndTtl(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("javatest","1");jedis.expire("javatest",10);System.out.println("等待3s后");Thread.sleep(3000);Long time = jedis.ttl("javatest");System.out.println("剩余的时间:" + time + "s");} catch (InterruptedException e) {throw new RuntimeException(e);}}

2.8 type测试

    public void type(){try(Jedis jedis = jedisPool.getResource()){jedis.flushAll();jedis.set("key1","1");String result1 = jedis.type("key1");System.out.println("key1类型为:" + result1);jedis.lpush("key2","1","2");String result2 = jedis.type("key2");System.out.println("key2类型为:" + result2);jedis.hset("key3","field1","1");String result3 = jedis.type("key3");System.out.println("key3类型为:" + result3);jedis.sadd("key4","1","2");String result4 = jedis.type("key4");System.out.println("key4类型为:" + result4);jedis.zadd("key5",10,"user1");String result5 = jedis.type("key5");System.out.println("key5类型为:" + result5);}}

        其余的命令不再演示,Jedis提供的Java客户端访问Redis的命令基本和Redis客户端的命令一致,使用很简单,只是需要注意返回值和变长参数(或者是Map来组织变长参数)。

3 SpringBoot集成Redis

3.1 配置文件

# Redis配置spring:redis:host: 127.0.0.1port: 8888

3.2 使用方法

3.2.1 引入依赖

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

        该依赖是SpringBoot集成的Redis依赖Spring Data Redis,SpringBoot 2内置的Redis是Lettuce实现,而不是Jedis实现,因此使用上有点区别。

3.2.2 注入Bean

    @Autowiredprivate StringRedisTemplate redisTemplate;

        这里StringRedisTemplate是已经交付给Spring管理的Bean,它是RedisTemplate的子类。RedisTemplate通过泛型控制是处理文本类型的数据还是处理字节类型的数据。

3.2.3 使用redis

@RequestMapping("/springbootRedis")@RestControllerpublic class RedisController {@Autowiredprivate StringRedisTemplate redisTemplate;@RequestMapping("/test")public void useRedis(){// 使用opsForXXX()方法得到对应类型的操作对象// string类型的操作redisTemplate.opsForValue().set("key","1");String result = redisTemplate.opsForValue().get("key");System.out.println("key:" + result);redisTemplate.delete("key");// list类型的操作redisTemplate.opsForList().leftPush("key", "a");redisTemplate.opsForList().leftPushAll("key", "b", "c", "d");List<String> values = redisTemplate.opsForList().range("key", 1, 2);System.out.println(values);redisTemplate.delete("key");// hash类型的操作redisTemplate.opsForHash().put("key", "name", "zhangsan");String value = (String) redisTemplate.opsForHash().get("key", "name");System.out.println(value);redisTemplate.opsForHash().delete("key", "name");boolean ok = redisTemplate.opsForHash().hasKey("key", "name");System.out.println(ok);redisTemplate.delete("key");// set类型的操作redisTemplate.opsForSet().add("key", "aaa", "bbb", "ccc");boolean ok1 = redisTemplate.opsForSet().isMember("key", "aaa");System.out.println(ok1);redisTemplate.opsForSet().remove("key", "aaa");long n = redisTemplate.opsForSet().size("key");System.out.println(n);redisTemplate.delete("key");// zset类型的操作redisTemplate.opsForZSet().add("key", "user1", 100);redisTemplate.opsForZSet().add("key", "user2", 98);redisTemplate.opsForZSet().add("key", "user3", 95);Set<String> values2 = redisTemplate.opsForZSet().range("key", 0, 2);System.out.println(values2);long n2 = redisTemplate.opsForZSet().count("key", 95, 100);System.out.println(n);redisTemplate.delete("key");}}

        这里的使用方法是先要用opsForXXX()方法获取不同类型的操作对象,再通过该操作对象来进行操作。具体的api可能和命令不一样,但是通过方法的名字也可以知道该方法对应的命令。

下篇文章:

Redis原理之持久化https://blog.csdn.net/sniper_fandc/article/details/149140995?fromshare=blogdetail&sharetype=blogdetail&sharerId=149140995&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

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

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

相关文章

Modbus 开发工具实战:ModScan32 与 Wireshark 抓包分析(一

引言 ** 在工业自动化领域&#xff0c;Modbus 协议犹如一座桥梁&#xff0c;连接着各种电子设备&#xff0c;实现它们之间高效的数据交互。从可编程逻辑控制器&#xff08;PLC&#xff09;到人机界面&#xff08;HMI&#xff09;&#xff0c;再到各类智能传感器&#xff0c;M…

Oracle SQL - 使用行转列PIVOT减少表重复扫描(实例)

[13/JUL/2025, Yusuf Leo, Oracle SQL Performance Tuning Series]我们经常会遇到从同一表中按不同维度取出不同区间的数据&#xff0c;再以相同的属性将这些数据分别汇总到一起的需求。这类需求往往迫使我们对同一个表反复去扫描&#xff0c;当原始数据量太大的时候&#xff0…

HTTP 请求方法详解:GET、POST、PUT、DELETE 等

在 HTTP 协议中&#xff0c;请求方法&#xff08;也称为 HTTP 动词&#xff09;定义了客户端希望对指定资源执行的操作类型。这些方法是 HTTP 报文的核心组成部分&#xff0c;决定了请求的目的和行为。 主要 HTTP 请求方法 1. GET 用途&#xff1a;获取资源 特点&#xff1a…

Android 代码热度统计(概述)

1. 前言 代码热度统计&#xff0c;在测试中一般也叫做代码覆盖率。一般得到代码覆盖率后就能了解整体样本在线上的代码使用情况&#xff0c;为无用代码下线提供依据。 做了一下调研&#xff0c;在Android中一般比较常用的是&#xff1a;JaCoCO覆盖率统计工具&#xff0c;它采…

RAG优化

RAG搭建本地AI知识库&#xff0c;在使用过程中遇到的三大痛点&#xff0c;以及相应的进阶方案。1. RAG知识库的三大痛点-- 内容理解不足&#xff1a;AI难以全面理解导入资料的内容&#xff0c;比如在向量编码时候&#xff0c;生硬的截断等导致分析结果不理想。eg: 知识库分割器…

Ubuntu 24.04 启用 root 图形登录

关键词&#xff1a;Ubuntu 24.04、root 登录、GDM、SSH、nano、配置文件一、前言 Ubuntu 默认禁用 root 账户 的图形与 SSH 登录&#xff0c;这是为了安全。但在某些场景&#xff08;如测试、救援、自动化脚本&#xff09;你可能需要 直接用 root 登录 GNOME 桌面。本文以 Ubun…

Jekyll + Chirpy + GitHub Pages 搭建博客

Chirpy 是适用于技术写作的简约、响应迅速且功能丰富的 Jekyll 主题&#xff0c;文档地址&#xff1a;https://chirpy.cotes.page/ &#xff0c;Github 地址&#xff1a;jekyll-theme-chirpy 。 1.开始 打开 chirpy-starter 仓库&#xff0c;点击按钮 Use this template -->…

学习 Flutter (一)

学习 Flutter (一) 1. 引言 什么是 Flutter&#xff1f; Flutter 是 Google 开发的一套开源 UI 框架&#xff0c;主要用于构建高性能、高保真、跨平台的应用程序。使用一套 Dart 编写的代码&#xff0c;开发者可以同时构建适用于&#xff1a; Android iOS Web Windows、mac…

Spring Boot 实现图片防盗链:Referer 校验与 Token 签名校验完整指南

Spring Boot 实现图片防盗链教程&#xff08;Referer 校验 Token 签名校验&#xff09;本文将详细讲解两种防盗链实现方案&#xff0c;并提供完整代码示例。方案一&#xff1a;Referer 校验通过检查 HTTP 请求头中的 Referer 字段判断来源是否合法。实现步骤创建 Referer 拦截…

从 JSON 到 Python 对象:一次通透的序列化与反序列化之旅

目录 一、为什么要谈 JSON 二、最快速上手&#xff1a;两把钥匙 dumps 与 loads 三、深入 dumps&#xff1a;参数是魔法棒 四、深入 loads&#xff1a;把风险挡在门外 五、文件级序列化&#xff1a;dump 与 load 六、处理中文与编码陷阱 七、异常场景与调试技巧 八、实…

Leetcode 3315. 构造最小位运算数组 II

1.题目基本信息 1.1.题目描述 给你一个长度为 n 的质数数组 nums 。你的任务是返回一个长度为 n 的数组 ans &#xff0c;对于每个下标 i &#xff0c;以下 条件 均成立&#xff1a; ans[i] OR (ans[i] 1) nums[i] 除此以外&#xff0c;你需要 最小化 结果数组里每一个 a…

黑搜小知识 | DNS域名解析过程是什么样的?

什么是DNS&#xff1f;DNS( Domain Name System)是“域名系统”的英文缩写&#xff0c;是一种组织成域层次结构的计算机和网络服务命名系统&#xff0c;它用于TCP/IP网络&#xff0c;它所提供的服务是用来将主机名和域名转换为IP地址的工作。举例来说&#xff0c;如果你要访问域…

MyBatis 使用教程及插件开发

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 本文的宗旨在于通过简单干净实践的方式教会读者&#xff0c;使用 SpringBoot 配置 MyBatis 并完成对插入、批量插入、修改、查询以及注解事务和编程事务的使用&#xff0c;通过扩展插件…

Maui劝退:用windows直接真机调试iOS,无须和Mac配对

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

【极客日常】后端任务动态注入执行策略的一种技术实现

近期做项目时遇到一个场景&#xff0c;是需要在后端任务执行时动态注入策略。具体而言&#xff0c;笔者负责的后端服务&#xff0c;可以理解是会在线上服务发布时&#xff0c;对服务风险做实时扫描&#xff0c;那么这个扫描就需要根据当前线上服务发布上下文&#xff0c;匹配对…

8. JVM类装载的执行过程

1. JVM介绍和运行流程-CSDN博客 2. 什么是程序计数器-CSDN博客 3. java 堆和 JVM 内存结构-CSDN博客 4. 虚拟机栈-CSDN博客 5. JVM 的方法区-CSDN博客 6. JVM直接内存-CSDN博客 7. JVM类加载器与双亲委派模型-CSDN博客 8. JVM类装载的执行过程-CSDN博客 9. JVM垃圾回收…

Linux操作系统之信号:信号的产生

前言&#xff1a;上篇文章我们大致讲解了信号的有关概念&#xff0c;为大家引入了信号的知识点。但光知道那些是远远不够的。本篇文章&#xff0c;我将会为大家自己的讲解一下信号的产生的五种方式&#xff0c;希望对大家有所帮助。一、键盘&#xff08;硬件&#xff09;产生信…

pdf拆分

文章目录 背景目标实现下载 背景 好不容易下载的1000页行业报告&#xff0c;领导非要按章节拆分成20份&#xff01;学术论文合集需要按作者拆分投稿&#xff0c;手动分页到怀疑人生…客户发来加密合同&#xff0c;要求每5页生成独立文档&#xff0c;格式还不能乱&#xff01; …

vue3使用mermaid生成图表,并可编辑

效果图实际代码<template><div class"mermaid-container" style"z-index: 99999" ref"wrapperRef"><!-- 控制栏 --><div class"control-bar"><div class"control-bar-flex control-bar-tab-wrap"…

tcp/quic 的滑动窗口

一、滑动窗口 rwnd&#xff1a; 接收端窗口&#xff0c;接收方在每次发送ACK确认报文时&#xff0c;会包含一个 rwnd (Receive Window Size) 字段&#xff0c;指明自己当前剩余的接收缓冲区大小&#xff08;即可用窗口&#xff09;&#xff0c;这里是否是socket的接收缓冲区&am…