redis zremove删除不掉【bug】
redis zremove删除不掉【bug】
- 前言
- 版权
- redis zremove删除不掉
- 错误产生
- 相关资源
- EldData
- EchartsTest
- DataService
- 解决
- 最后
前言
2024-4-12 20:35:21
以下内容源自《【bug】》
仅供学习交流使用
版权
禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://blog.csdn.net/qq_51625007
禁止其他平台发布时删除以上此话
redis zremove删除不掉
测试一:
- 调用添加数据:testAddData20
- 调用修改数据:testUpdateData
- 调用删除方法:testRemoveData20
结果:调用删除新的数据,旧的数据就会重新出现
1.
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}
2.
true
{date=[2024-04-13], rate1=[22], rate2=[22], id=[20]}
3.
1
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}
测试二:
- 调用添加数据:testAddData
- 调用删除方法:testRemoveData20
结果:删除成功,只有数据完全一样才行
1.
{date=[2024-04-13, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12], rate1=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], rate2=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], id=[20, 9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1]}
2.
1
{date=[2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12, 2024-04-12], rate1=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], rate2=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1], id=[9, 8, 7, 6, 5, 4, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 3, 2, 1]}
错误产生
为什么可以修改,但是不能删除
在上面的代码中,虽然使用了自定义序列化器和比较方法来实现根据特定条件或属性删除数据,但是在实际操作中,Redis有序集合的remove方法确实只能删除完全相同的数据。
这是因为在Redis的有序集合中,元素是通过score进行排序的,而remove方法是根据元素的值来删除的。如果元素的值完全相同,那么remove方法可以成功删除。但是如果元素的值中的某些属性或条件不同,即使其他属性相同,remove方法也无法删除这样的数据。
因此,如果希望根据特定属性或条件删除数据,可以考虑使用其他数据结构或方法来实现,比如使用Redis的哈希表来存储数据,然后通过特定的属性作为键来删除数据。或者在应用层进行数据的筛选和删除操作,然后再写回Redis中。
不能根据equals方法判断的吗
对于Java中的对象,可以通过重写equals方法来自定义判断两个对象是否相等。但是在Redis中,数据是以字符串或字节数组的形式存储的,并没有对对象的equals方法进行支持。
在Redis中,有序集合的remove方法是根据元素的值来删除的,而不是根据对象的equals方法。只有完全相同的值才可以被成功删除,否则无法删除。
如果希望根据对象的equals方法来判断是否删除数据,通常需要在应用层进行操作,先获取到数据再进行比较,然后再删除数据。或者可以使用其他数据结构或方法来实现根据对象的equals方法来删除数据。Redis本身并不提供根据对象的equals方法进行删除的功能。
应该是与序列化和反序列化有关。
相关资源
EldData
package com.jsss.echarts.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;import java.sql.Date;
import java.util.Objects;@Data
@NoArgsConstructor
@AllArgsConstructorpublic class EldData {String id;Integer rate1;Integer rate2;Date date;public EldData(String id, Date date) {this.id = id;this.date = date;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;EldData eldData = (EldData) o;return Objects.equals(id, eldData.id) && Objects.equals(date, eldData.date);}@Overridepublic int hashCode() {return Objects.hash(id, date);}@Overridepublic String toString() {return "EldData{" +"rate1=" + rate1 +", rate2=" + rate2 +", date=" + date +'}';}
}
EchartsTest
package com.jsss.echarts.service;import com.jsss.echarts.entity.EldData;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;@Service
public class DataService implements Constant {@AutowiredRedisTemplate redisTemplate;//返回数据链表public HashMap<String,ArrayList> searchMap(Integer userId){HashMap<String,ArrayList> map=new HashMap<>();List<EldData> dataList = search(userId);List<String> fieldNames = new ArrayList<>();Class<?> dataClass = EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());map.put(field.getName(),new ArrayList<>());}for (EldData data : dataList) {for (String fieldName : fieldNames) {ArrayList<Object> rowData =map.get(fieldName);try {Field field = dataClass.getDeclaredField(fieldName);field.setAccessible(true);rowData.add(field.get(data));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}map.put(fieldName,rowData);}}return map;}//搜索数据public List<EldData> search(Integer userId) {String key= ELD_DATA +userId;Set set = redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据return set !=null?new ArrayList<>(set):new ArrayList<>();}// 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,如果数据已存在则会覆盖public boolean updateData(Integer userId, EldData newData) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, newData, newData.getDate().getTime());}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}@Testpublic void test2() {System.out.println("1.");testAddData20();System.out.println("2.");testUpdateData();System.out.println("3.");testRemoveData();}}
DataService
package com.jsss.echarts.service;import com.jsss.echarts.entity.EldData;
import com.jsss.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;@Service
public class DataService implements Constant {@AutowiredRedisTemplate redisTemplate;//返回数据链表public HashMap<String,ArrayList> searchMap(Integer userId){HashMap<String,ArrayList> map=new HashMap<>();List<EldData> dataList = search(userId);List<String> fieldNames = new ArrayList<>();Class<?> dataClass = EldData.class;// 获取 OldData 类的所有属性名Field[] fields = dataClass.getDeclaredFields();for (Field field : fields) {fieldNames.add(field.getName());map.put(field.getName(),new ArrayList<>());}for (EldData data : dataList) {for (String fieldName : fieldNames) {ArrayList<Object> rowData =map.get(fieldName);try {Field field = dataClass.getDeclaredField(fieldName);field.setAccessible(true);rowData.add(field.get(data));} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}map.put(fieldName,rowData);}}return map;}//搜索数据public List<EldData> search(Integer userId) {String key= ELD_DATA +userId;Set set = redisTemplate.opsForZSet().reverseRange(key, 0, 19);// 获取分数最高的20个数据return set !=null?new ArrayList<>(set):new ArrayList<>();}// 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,如果数据已存在则会覆盖public boolean updateData(Integer userId, EldData newData) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, newData, newData.getDate().getTime());}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}}
解决
不知道怎么解决
修改更新业务
先删除旧的,再添加新的
保证只有一个equals对象
// 将数据存储到有序集合中,分数为日期的时间戳public boolean addData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().add(key, data,data.getDate().getTime());}// 更新数据,先删除数据,后增加新数据public boolean updateData(Integer userId,EldData oldData,EldData newData) {long res=removeData(userId,oldData);if (res==0){//没有旧数据,就修改失败return false;}return addData(userId, newData);}// 删除指定的数据public long removeData(Integer userId, EldData data) {String key= ELD_DATA +userId;return redisTemplate.opsForZSet().remove(key, data);}
对应的测试方法
@Testpublic void testUpdateData() {EldData oldData=new EldData(String.valueOf(20),20,20,date);EldData newData=new EldData(String.valueOf(20),22,22,date);System.out.println(dataService.updateData(userId, oldData,newData));testSearchMap();}
测试test1,结果:
1.
{date=[2024-04-13], rate1=[20], rate2=[20], id=[20]}
2.
true
{date=[2024-04-13], rate1=[22], rate2=[22], id=[20]}
3.
1
{date=[], rate1=[], rate2=[], id=[]}
最后
2024-4-12 21:31:23
我们都有光明的未来
祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦
相关文章:
redis zremove删除不掉【bug】
redis zremove删除不掉【bug】 前言版权redis zremove删除不掉错误产生相关资源EldDataEchartsTestDataService 解决 最后 前言 2024-4-12 20:35:21 以下内容源自《【bug】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星…...
对象的本地保存
对象的本地保存 对象的创建和保存 对象的特点: 对象“生活”在内存空间中,因此,程序一旦关闭,这些对象也都会被CLR的垃圾回收机制销毁。程序第二次运行时,对象会以“全新”的状态出现,无法保留上次对象的运行状态。…...

PostgreSQL入门到实战-第二十一弹
PostgreSQL入门到实战 PostgreSQL中表连接操作(五)官网地址PostgreSQL概述PostgreSQL中RIGHT JOIN命令理论PostgreSQL中RIGHT JOIN命令实战更新计划 PostgreSQL中表连接操作(五) 使用PostgreSQL RIGHT JOIN连接两个表,并从右表返回行 官网地址 声明: 由于操作系统…...

李彦宏放话:百度AI大模型绝不抢开发者饭碗
关注卢松松,会经常给你分享一些我的经验和观点。 昨晚,李彦宏内部讲话称:AI大模型开源意义不大,百度绝不抢开发者饭碗。 但你一定要说话算话哦,可千万别说:“我永远不做手机,谁再敢提做手机就给…...
es 倒排索引
es 倒排索引TRee 倒排索引树(TRee)通常指的是Elasticsearch中用于支持高速搜索的一种数据结构。它是一种树状结构,可以通过特定的词项(terms)来快速定位包含这些词项的文档。 在Elasticsearch中,倒排索引…...

阿里云服务器公网带宽费用全解析(不同计费模式)
阿里云服务器公网带宽怎么收费?北京地域服务器按固定带宽计费一个月23元/M,按使用流量计费0.8元/GB,云服务器地域不同实际带宽价格也不同,阿里云服务器网aliyunfuwuqi.com分享不同带宽计费模式下带宽收费价格表: 公网…...
python-pytorch实现lstm模型预测文本输出0.1.00
python-pytorch实现lstm模型预测文本输出0.1.00 数据参考效果分词到数组准备数数据查看频次获取vacab生成输入数据训练测试连续预测有问题还需要完善 数据 一篇新闻:https://news.sina.com.cn/c/2024-04-12/doc-inarqiev0222543.shtml 参考 https://blog.csdn.net/qq_1953…...

77、WAF攻防——权限控制代码免杀异或运算变量覆盖混淆加密传参
文章目录 WAF规则webshell免杀变异 WAF规则 函数匹配 工具指纹 webshell免杀变异 php 传参带入 eval可以用assert来替换,assert也可以将字符串当作php代码执行漏洞 php 变量覆盖 php 加密 使用加密算法对php后门进行加密 php 异或运算 简化:无字符webshellP 无数字字母rc…...
A12 STM32_HAL库函数 之 HAL-ETH通用驱动 -- A -- 所有函数的介绍及使用
A12 STM32_HAL库函数 之 HAL-ETH通用驱动 -- A -- 所有函数的介绍及使用 1 通用定时器(TIM)预览1.1 HAL_ETH_Init1.2 HAL_ETH_DeInit1.3 HAL_ETH_DMATxDescListInit1.4 HAL_ETH_DMARxDescListInit1.5 HAL_ETH_MspInit1.6 HAL_ETH_MspDeInit1.7 HAL_ETH_T…...
Linux从入门到精通 --- 1.初始Linux
文章目录 第一章:1.1 Linux的诞生1.2 Linux系统内核1.3 Linux系统发行版 第一章: 1.1 Linux的诞生 1991年由林纳斯 托瓦兹创立并发展至今称为服务器操作系统领域的核心系统。 1.2 Linux系统内核 Linux内核提供了系统的主要功能,甚至是开源…...

linux使用docker实现redis主从复制和哨兵模式
目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像: 然后docker run创建container容器 首先…...

新版chrome 解决在http协议下无法调用摄像头和麦克风的问题(不安全)
解决办法:亲测可行 chrome浏览器地址栏中输入chrome://flags/#unsafely-treat-insecure-origin-as-secure,回车,如下图,将该选项置为Enabled, edge浏览器打开:edge://flags/#unsafely-treat-insecure-orig…...
机器学习入门项目二(逻辑回归)
如果输入数据长度为2,上一章的方程就无法满足需求了,需要修改方程: z w 1 x w 2 y b zw_1xw_2yb zw1xw2yb 数据产生器: import matplotlib.pyplot as plt import numpy as npclass DataGenerator2Input:"""…...
C++类引用的好处
简化代码:引用可以简化代码,使其更加易读和易懂。通过使用引用,可以避免在函数参数中复制大型对象,从而提高代码的效率和性能。 传递大型对象的效率高:使用引用作为函数参数传递大型对象时,不需要进行对象…...

从零自制docker-9-【管道实现run进程和init进程传参】
文章目录 命令行中输入参数长度过长匿名管道从父进程到子进程传参[]*os.File{}os.NewFile和io.ReadAllexe.LookPathsyscall.Execstrings.Split(msgStr, " ")/bin/ls: cannot access : No such file or directory代码 命令行中输入参数长度过长 用户输入参数过长或包…...
全量知识系统 程序详细设计 之 三种“活物” 之1(QA百度搜索 )
Q1. 今天聊聊 全知系统中 三种“活物”。先从他们的一个简单描述开始: 自主:计算机“集群”的“沉”与“浮”; 自然:AI “众生”的“世”和“界” ;自由:人类 “公民”的“宇”或“宙”。 全知系统中的三…...

QT 线程之movetothread
上文列举了qt中线程的几种方法,其中2种方法最为常见。 这两种方法都少不了QThread类,前者继承于QThread类,后者复合QThread类。 本文以实例的方式描述了movetothread()这种线程的方法,将QObject的子类移动…...

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示
Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时,您可能收到“Daemons using outdated libraries”,“Which services should be restarted?”的提示,提示下面列出备选的重启服务,如下。 使用以下命令,能够…...

跟TED演讲学英文:The inside story of ChatGPT‘s astonishing potential by Greg Brockman
The inside story of ChatGPT’s astonishing potential Link: https://www.ted.com/talks/greg_brockman_the_inside_story_of_chatgpt_s_astonishing_potential Speaker: Greg Brockman Date:April 2023 文章目录 The inside story of ChatGPTs astonishing potentialIntro…...

mybatis05:复杂查询:(多对一,一对多)
mybatis05:复杂查询:(多对一,一对多) 文章目录 mybatis05:复杂查询:(多对一,一对多)前言:多对一 : 关联 : 使用associatio…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...