详细分析Redis中数值乱码的根本原因以及解决方式

目录

  • 前言
  • 1. 问题所示
  • 2. 原理分析
  • 3. 拓展

前言

对于这方面的相关知识推荐阅读:

  1. Redis框架从入门到学精(全)
  2. Java关于RedisTemplate的使用分析 附代码
  3. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)

1. 问题所示

某些信息存储在缓存中,对此修改缓存,想通过可视化的Redis Desktop来操作,但是发现都是二进制的数据,不好操作:
在这里插入图片描述

于是想着以命令行的方式修改,但又怕改错,毕竟都是难以读懂的二进制数据,如图所示:(由于信息比较隐私,此处打码了)

在这里插入图片描述

2. 原理分析

RedisTemplate 存储的数据通常是二进制的。Redis 是一个键值存储系统,它存储的值可以是字符串、二进制数据、甚至是序列化的对象。

RedisTemplate 是 Spring Data Redis 提供的一个类,用于在 Spring 应用中与 Redis 进行交互。

它提供了一种在 Java 对象和 Redis 数据之间进行序列化和反序列化的机制。
默认情况下,RedisTemplate 使用 JDK 的序列化机制将 Java 对象转换为二进制数据,并存储在 Redis 中。

3. 拓展

在使用Redis作为数据存储时,合理的键值序列化配置和RedisTemplate的使用方式对于应用性能和数据可维护性至关重要。

默认情况下,Spring Data Redis使用JdkSerializationRedisSerializer作为RedisTemplate的默认序列化器

这意味着键和值都将以Java对象的二进制形式进行序列化,并以字节流的方式存储在Redis中。

  • 不对值进行额外序列化的理由:虽然值以二进制形式存储,但在Java代码中获取值时会进行反序列化,因此这不会影响业务逻辑和数据的正确性。
    同时,对值进行额外的序列化可能会限制存储的数据类型,例如将值序列化为字符串将仅能存储字符串类型的值。

  • 额外序列化的场景
    如果需要存储复杂的数据结构或非字符串类型的值,可以选择配置RedisTemplate使用其他序列化器,例如JSON序列化器或自定义序列化器。
    这样可以更灵活地存储各种类型的数据,但需要注意在读取时正确地反序列化。

  • 特殊值的处理
    对于包含特殊类型(如LocalDateTime、LocalDate、LocalTime等)的值,可能需要注意转换为字符串或选择合适的序列化方式。

通过理解Redis默认行为和灵活运用RedisTemplate,可以更好地应对不同类型数据的存储需求,从而优化系统性能并提升开发效率

给出一个Demo代码更加容易懂:

先引入这两个依赖包:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.6.5.RELEASE</version> <!-- 使用你项目中的实际版本 -->
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.0</version> <!-- 使用你项目中的实际版本 -->
</dependency>

对key进行可视化:

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

public class Demo {
    public static void main(String[] args) {

        // 创建 Redis 连接配置
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName("localhost");
        jedisConnectionFactory.setPort(6379);
        // jedisConnectionFactory.setPassword(RedisPassword.of("your-redis-password"));

        // 手动调用 afterPropertiesSet()
        jedisConnectionFactory.afterPropertiesSet();

        // 创建 RedisTemplate 实例
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //设置String类型的key设置序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置Hash类型的key设置序列化器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        redisTemplate.afterPropertiesSet();

        // 存储字符串
        redisTemplate.opsForValue().set("message", "Hello, Redis!");

        // 获取字符串
        String message = (String) redisTemplate.opsForValue().get("message");
        System.out.println("Message: " + message);

        // 存储哈希
        HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
        hashOperations.put("user", "id", "1");
        hashOperations.put("user", "name", "码农研究僧");

        // 获取哈希
        String userId = hashOperations.get("user", "id");
        String userName = hashOperations.get("user", "name");
        System.out.println("User ID: " + userId);
        System.out.println("User Name: " + userName);
    }
}

如果不对key可视化,只需要删除这两行代码即可:

//设置String类型的key设置序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置Hash类型的key设置序列化器
redisTemplate.setHashKeySerializer(new StringRedisSerializer());

截图如下:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣 第 383 场周赛 解题报告 | KMP

力扣 第 383 场周赛 解题报告 | KMP 链接 前言 一个人能走的多远不在于他在顺境时能走的多快&#xff0c;而在于他在逆境时多久能找到曾经的自己。 T1 修改矩阵 思路&#xff1a;模拟 时间复杂度&#xff1a; O ( m n ) O(mn) O(mn) class Solution:def modifiedMatrix(se…

读书笔记之《重塑大脑重塑人生》:大脑强大的可塑性

《重塑大脑重塑人生》作者是诺曼道伊奇&#xff0c;原作名: The Brain That Changes Itself: Stories of Personal Triumph from the Frontiers of Brain Science &#xff0c;于 2015-1-20出版。 诺曼•道伊奇&#xff08;Norman Doidge&#xff09;是医学博士&#xff0c;精…

leetcode题目记录

文章目录 单调栈[127. 单词接龙](https://leetcode.cn/problems/word-ladder/)[139. 单词拆分](https://leetcode.cn/problems/word-break/)[15. 三数之和](https://leetcode.cn/problems/3sum/)[140. 单词拆分 II](https://leetcode.cn/problems/word-break-ii/)[113. 路径总和…

C++ STL string类使用及实现详解

1. string简介 C语言中&#xff0c;可以用字符数组来存储字符串&#xff0c;如&#xff1a; char ch[] "hello world"; C中&#xff0c;可以使用string类对象来存储字符串&#xff0c;使用起来比C语言中的字符数组要方便得多&#xff0c;而且不用考虑容量的问题。…

C#,普洛尼克数(Pronic Number)的算法与源代码

1 普洛尼克数(pronic number) 普洛尼克数(pronic number)&#xff0c;也叫矩形数、欧波朗数(oblong number)&#xff0c;是两个连续非负整数的积&#xff0c;即mn*(n1)。第n个普洛尼克数侪是n个三角形数个两倍。 2 计算结果 3 源程序 using System; namespace Legalsoft.Tru…

c++之说_14|左值引用与右值引用

提起左右值引用我就头疼 左值&#xff1a; 1、在内存中开辟了空间的便叫左值 2、左值不一定可以赋值 如字符串常量 3、左值可以取地址 右值&#xff1a; 1、在内存中没有开辟空间的 2、右值无法取地址 如&#xff1a; 立即数&#xff08;1&#xff0c;2&#xff0c;3…

Unity类银河恶魔城学习记录7-1 P67 Sword Throw Skill State源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Sword_Skill.cs using System.Collections; using System.Collections.Gen…

nba2k24 韩旭面补

nba2k23-24 韩旭面补 nba2k23-nba2k24通用 韩旭面补 下载地址&#xff1a; https://www.changyouzuhao.cn/9605.html

【原创 附源码】Flutter安卓及iOS海外登录--Tiktok登录最详细流程

最近接触了几个海外登录的平台&#xff0c;踩了很多坑&#xff0c;也总结了很多东西&#xff0c;决定记录下来给路过的兄弟坐个参考&#xff0c;也留着以后留着回顾。更新时间为2024年2月7日&#xff0c;后续集成方式可能会有变动&#xff0c;所以目前的集成流程仅供参考&#…

Flex布局 (上万字)超详细讲解 这篇就够了

一、Flex概述 Flex布局&#xff0c;全称为“Flexible Box Layout”&#xff0c;意为“弹性盒布局”。它是一种现代的CSS布局模式&#xff0c;旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间&#xff0c;即使它们的大小未知或动态变化。 Flex布局的主要特点…

Unity类银河恶魔城学习记录6-2 P66 Clone‘s Attack源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Clone_Skill.cs using System.Collections; using System.Collections.Gen…

二叉搜索树删除操作的递归与非递归写法

如何进行删除操作 对于二叉搜索树的删除操作&#xff0c;主要分为以下3种情况讨论&#xff1a; 1、删除的结点没有左右孩子 2、删除的结点只有一个孩子 3、删除的结点有左右孩子 所以&#xff0c;我们将会用if…else…分为最多3种情况讨论&#xff08;实际上只分了两种&#x…

关于java的多线程初识

关于java的多线程初识 我们从今天开始&#xff0c;正式学习java的多线程&#xff0c;我们在前面的文章中学习到了java的基础&#xff0c; 但是距离我们工作实战还差的很远&#xff0c;我们学习好了基础&#xff0c;以后的文章会逐步的深入&#xff0c;去讲解各种前端框架&…

同余数论性质

同余概念 当 a%m b%m&#xff0c;说明a和b同余&#xff0c;写作若 a≡b(mod m) 性质 衍生出几条性质 1.m | abs(a-b)&#xff0c;即|a-b|是m的倍数。&#xff08;注意&#xff0c;0是任何数的倍数&#xff09; 2.当a≡b(mod m)&#xff0c;c≡d(mod m)&#xff0c; 有ac…

IDEA Ultimate下载(采用JetBrain学生认证)

IDEA Ultimate版本下载 Ulitmate是无限制版&#xff08;解锁所有插件&#xff0c;正版需要付费。学生可以免费申请许可&#xff09;Community是开源社区版本&#xff08;部分插件不提供使用&#xff0c;比如Tomcat插件。免费&#xff09; 我们将通过学生认证获取免费版。 Je…

【vue3学习笔记】shallowReactive与shallowRef;readOnly与shallowReadOnly;toRaw与markRaw

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 课程 P158节 《shallowReactive与shallowRef》笔记&#xff1a; reactive()与shallowReactive()&#xff1a;reactive()处理后的数据是响应式的&#xff0c;对象内嵌套的深层结构全部是响应式的。shallowReactive()处理后的数据…

闭环控制系统手自动策略(车辆定速巡航应用)

闭环控制系统的手自动策略并不会完全一样&#xff0c;不同的行业&#xff0c;基于不同的规范和安全考虑给出的手自动策略是不一样的&#xff0c;这里我们介绍汽车行业定速巡航应用。 PID闭环控制系统手自动切换的相关文章&#xff0c;还可以查看下面链接&#xff1a; 无扰切换…

2013-2022年上市公司迪博内部控制指数、内部控制分项指数数据

2013-2022年上市公司迪博内部控制指数、分项指数数据 1、时间&#xff1a;2013-2022年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、内部控制指数、战略层级指数、经营层级指数、报告可靠指数、合法合规指数、资产安全…

基于Locust实现MQTT协议服务的压测脚本

一、背景简介 业务背景大概介绍一下&#xff0c;就是按照国标规定&#xff0c;车辆需要上传一些指定的数据到ZF的指定平台&#xff0c;同时车辆也会把数据传到企业云端服务上&#xff0c;于是乎就产生了一些性能需求。 目前我们只是先简单的进行了一个性能场景的测试&#xf…

C++进阶(十五)C++的类型转换

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、C语言中的类型转换二、为什么C需要四种类型转换三、C强制类型转换1、static_cast2、reint…