详解Redis中数值乱码的根本原因以及解决方式
作者:码农研究僧
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());
截图如下:
以上就是详解Redis中数值乱码的根本原因以及解决方式的详细内容,更多关于Redis数值乱码的资料请关注脚本之家其它相关文章!