尚硅谷redis 第97节 redisTmplate下答疑

        int keyId = ThreadLocalRandom.current().nextInt(1000)+1;
        String serialNo = UUID.randomUUID().toString();

        String key = ORDER_KEY+keyId;
        String value = "京东订单"+serialNo;

        redisTemplate.opsForValue().set(key,value);
-----------这段执行后,redis里面相应的值有乱码吗?       
 //设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
加上这些之后呢?那不是一个简单的字符串还要存放成json带花括号的那种?


在默认情况下,Spring Data Redis 会使用 `JdkSerializationRedisSerializer` 来序列化和反序列化对象。这种序列化方式会将对象序列化为字节数组,因此在 Redis 中存储的值看起来可能像是乱码。

如果你希望以 JSON 格式存储数据,可以使用 `GenericJackson2JsonRedisSerializer` 进行序列化。这样,存储在 Redis 中的值将是 JSON 格式的字符串,而不是字节数组。

### 使用 `GenericJackson2JsonRedisSerializer`

#### 1. 设置 `ValueSerializer` 为 `GenericJackson2JsonRedisSerializer`
你可以在配置类中设置 `RedisTemplate` 的 `ValueSerializer`,如下所示:

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 设置key序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value序列化方式
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        return template;
    }
}
```

#### 2. 使用 `RedisTemplate` 存储数据
在你的业务逻辑中使用 `RedisTemplate` 存储数据时,值会被序列化为 JSON 格式:

```java
import lombok.extern.slf4j.Slf4j;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void createOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String serialNo = UUID.randomUUID().toString();
        String key = "ORDER_KEY" + keyId;
        String value = "京东订单" + serialNo;

        redisTemplate.opsForValue().set(key, value);

        log.info("***key:{}", key);
        log.info("***value:{}", value);
    }
}
```

### 结果
在 Redis 中查看存储的值时,如果使用 `GenericJackson2JsonRedisSerializer`,值会以 JSON 格式存储。例如:

```json
"ORDER_KEY123": "\"京东订单123e4567-e89b-12d3-a456-426614174000\""
```

### 解释
- **字符串值存储为 JSON 格式**:
  - `GenericJackson2JsonRedisSerializer` 会将对象序列化为 JSON 字符串,即使是简单的字符串也会被序列化为带引号的 JSON 字符串。
  - 例如,`"京东订单123e4567-e89b-12d3-a456-426614174000"` 会被序列化为 `"\"京东订单123e4567-e89b-12d3-a456-426614174000\""`。

- **读取值**:
  - 当你从 Redis 中读取值时,`GenericJackson2JsonRedisSerializer` 会自动反序列化为原始对象类型。在这个例子中,会反序列化为原始字符串。

### 总结
使用 `GenericJackson2JsonRedisSerializer` 可以确保你的数据以 JSON 格式存储在 Redis 中。这对于调试和查看存储的数据非常有用,因为 JSON 格式更容易阅读和理解。尽管简单字符串会被序列化为带引号的 JSON 字符串,但这不影响你在应用程序中读取和使用这些值。


===============
value里面为什么还要存key

在你提供的代码和示例中,`value` 并没有存储 `key`,而是存储了一个带有前缀 "京东订单" 的 UUID 字符串。可能是因为 JSON 序列化的结果让你误以为 `value` 中包含了 `key`。让我们更详细地解释一下。

### 代码回顾

```java
int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
String serialNo = UUID.randomUUID().toString();
String key = "ORDER_KEY" + keyId;
String value = "京东订单" + serialNo;

redisTemplate.opsForValue().set(key, value);

log.info("***key:{}", key);
log.info("***value:{}", value);
```

在上面的代码中:
- `key` 是一个字符串,格式为 `"ORDER_KEY" + keyId`。
- `value` 是一个字符串,格式为 `"京东订单" + serialNo`。

### 使用 `GenericJackson2JsonRedisSerializer`

当你使用 `GenericJackson2JsonRedisSerializer` 进行序列化时,字符串 `value` 会被序列化为 JSON 格式的字符串。对于简单的字符串,`GenericJackson2JsonRedisSerializer` 会将其包装在引号中。

### 示例

假设 `keyId` 为 `123`,`serialNo` 为 `123e4567-e89b-12d3-a456-426614174000`,那么:

- `key` 为 `"ORDER_KEY123"`。
- `value` 为 `"京东订单123e4567-e89b-12d3-a456-426614174000"`。

存储到 Redis 中时,使用 `GenericJackson2JsonRedisSerializer`,`value` 会被序列化为带引号的 JSON 字符串:

```json
"ORDER_KEY123": "\"京东订单123e4567-e89b-12d3-a456-426614174000\""
```

### 解释

- **键 `ORDER_KEY123`**:这是你设置的 Redis 键。
- **值 `"\"京东订单123e4567-e89b-12d3-a456-426614174000\""`**:这是被 `GenericJackson2JsonRedisSerializer` 序列化后的值。注意,整个字符串被额外的引号包裹,这是因为 JSON 序列化的结果。

### 结论

`value` 并没有存储 `key`,而是存储了一个带有前缀 "京东订单" 的 UUID 字符串。由于 `GenericJackson2JsonRedisSerializer` 的序列化机制,字符串会被包裹在引号中,这可能让你误以为 `value` 中包含了 `key`。

### 如何验证

你可以通过从 Redis 中读取值并进行反序列化来验证这一点:

```java
String storedValue = (String) redisTemplate.opsForValue().get(key);
log.info("***Stored value: {}", storedValue);
```

读取的 `storedValue` 应该是 `"京东订单123e4567-e89b-12d3-a456-426614174000"`,与原始的 `value` 相同。
=================
"ORDER_KEY123": "\"京东订单123e4567-e89b-12d3-a456-426614174000\""
这不就是value吗?里面没key吗?ORDER_KEY123是什么!而且还没有花括号,是对象吗?不是应该value是个字符串吗?存这么多不冗余了吗

抱歉,我之前的解释可能有些混淆。让我们更清晰地梳理一下。

### 解释 Redis 中的键值对

1. **键(Key)**:
   - 在你的代码中,`key` 是 `"ORDER_KEY" + keyId`,例如 `"ORDER_KEY123"`。这是 Redis 中存储数据的键。
   
2. **值(Value)**:
   - `value` 是 `"京东订单" + serialNo`,例如 `"京东订单123e4567-e89b-12d3-a456-426614174000"`。这是 Redis 中存储的数据。

### 使用 `GenericJackson2JsonRedisSerializer`

当你使用 `GenericJackson2JsonRedisSerializer` 进行序列化时,值会被序列化为 JSON 格式的字符串。对于简单的字符串,`GenericJackson2JsonRedisSerializer` 会将其包装在引号中。

### 示例

假设 `keyId` 为 `123`,`serialNo` 为 `123e4567-e89b-12d3-a456-426614174000`,那么:

- `key` 为 `"ORDER_KEY123"`。
- `value` 为 `"京东订单123e4567-e89b-12d3-a456-426614174000"`。

存储到 Redis 中时,使用 `GenericJackson2JsonRedisSerializer`,`value` 会被序列化为带引号的 JSON 字符串:

```json
"ORDER_KEY123": "\"京东订单123e4567-e89b-12d3-a456-426614174000\""
```

### 解释

- **键 `ORDER_KEY123`**:这是 Redis 中存储数据的键。
- **值 `"\"京东订单123e4567-e89b-12d3-a456-426614174000\""`**:这是被 `GenericJackson2JsonRedisSerializer` 序列化后的值。注意,整个字符串被额外的引号包裹,这是因为 JSON 序列化的结果。

### 结论

- **键**:`ORDER_KEY123` 是 Redis 中的键。
- **值**:`"京东订单123e4567-e89b-12d3-a456-426614174000"` 是 Redis 中存储的值,但被 `GenericJackson2JsonRedisSerializer` 序列化后会被额外的引号包裹。

### 是否冗余

如果你只是存储简单的字符串值,使用 `GenericJackson2JsonRedisSerializer` 可能显得有些冗余,因为它会把简单的字符串也当作 JSON 进行处理,增加了额外的引号。

### 如何避免冗余

如果你只是想存储和读取简单的字符串,可以使用 `StringRedisSerializer` 来处理值的序列化和反序列化:

#### 修改配置

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 设置key和value的序列化方式为String
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());

        return template;
    }
}
```

#### 使用 `RedisTemplate` 存储数据

```java
import lombok.extern.slf4j.Slf4j;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void createOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String serialNo = UUID.randomUUID().toString();
        String key = "ORDER_KEY" + keyId;
        String value = "京东订单" + serialNo;

        redisTemplate.opsForValue().set(key, value);

        log.info("***key:{}", key);
        log.info("***value:{}", value);
    }
}
```

这样存储到 Redis 中的值就是一个简单的字符串,没有额外的引号:

```json
"ORDER_KEY123": "京东订单123e4567-e89b-12d3-a456-426614174000"
```

### 总结

- **键**:`ORDER_KEY123` 是 Redis 中的键
========================
StringRedisSerializer存放中文会乱码吗

使用 `StringRedisSerializer` 存储中文不会出现乱码问题。`StringRedisSerializer` 默认使用 UTF-8 编码来处理字符串,因此可以正确处理中文字符。

### 示例

#### 配置 `RedisTemplate`

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        // 设置key和value的序列化方式为String
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());

        return template;
    }
}
```

#### 使用 `RedisTemplate` 存储和读取中文数据

```java
import lombok.extern.slf4j.Slf4j;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void createOrder() {
        int keyId = ThreadLocalRandom.current().nextInt(1000) + 1;
        String serialNo = UUID.randomUUID().toString();
        String key = "ORDER_KEY" + keyId;
        String value = "京东订单" + serialNo;

        redisTemplate.opsForValue().set(key, value);

        log.info("***key:{}", key);
        log.info("***value:{}", value);
    }

    public void readOrder(int keyId) {
        String key = "ORDER_KEY" + keyId;
        String value = redisTemplate.opsForValue().get(key);

        log.info("***Read key:{}", key);
        log.info("***Read value:{}", value);
    }
}
```

### 测试

```java
public class RedisTest {
    public static void main(String[] args) {
        // 假设我们已经有Spring Context和OrderService的Bean
        OrderService orderService = context.getBean(OrderService.class);

        // 创建一个订单
        orderService.createOrder();

        // 读取订单
        orderService.readOrder(123); // 假设 keyId 为 123
    }
}
```

### 结果

在 Redis 中存储的数据将是这样的:

```json
"ORDER_KEY123": "京东订单123e4567-e89b-12d3-a456-426614174000"
```

读取时,`value` 将正确显示为 `"京东订单123e4567-e89b-12d3-a456-426614174000"`,没有乱码。

### 总结

使用 `StringRedisSerializer` 存储和读取中文数据不会出现乱码问题,因为它使用 UTF-8 编码处理字符串。这样可以确保中文字符能够正确存储和读取。

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

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

相关文章

②PROFINET转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 PROFINET 转 Modbus TCP &#xff08;接上一章&#xff09; 配置使用 与 PROFINET 主站进行组态说明 这里介绍与西门子 PLC 的…

git分支模型

定义分支 长期分支 指长期存在的分支&#xff0c;也叫固定分支 developmaster 短期分支 短分支没有固定的分支名。但是有分支名规范 feature分支hotfix分支 分支模型 暂时无法在文档外展示此内容 参考 分支的目的是隔离&#xff0c;但多一个分支也意味着维护成本的增加。…

NFT Insider #152:The Sandbox Alpha 第4季开启

市场数据 加密艺术及收藏品新闻 Realm of Historia 推出首个以古老文化遗址为主题的 NFT 系列 专注于文化遗产保护的区块链平台 Realm of Historia 正通过推出首个 NFT 系列扩大其全球影响力。该系列以亚美尼亚的古代遗址 Carahunge 为主题&#xff0c;这一遗址已有 7500 多年…

EDM邮件营销,如何确保高频率发送不触发限制

EDM邮件营销需选对平台&#xff0c;遵守反垃圾邮件法规&#xff0c;高效管理邮件列表&#xff0c;合理制定发送频率&#xff0c;优化内容与设计&#xff0c;用智能化工具测试与优化&#xff0c;监控送达和反馈&#xff0c;维持良好ISP关系&#xff0c;确保高效安全发送不封号。…

13.3寸三防平板大尺寸+高速运行提升工业软件操作体验

在工业领域&#xff0c;移动设备的应用日益广泛&#xff0c;其性能直接影响着工作效率和数据安全。传统的工业平板电脑常常面临着屏幕尺寸过小、运行速度缓慢、以及抗环境能力不足等问题&#xff0c;这些都制约了工业软件的流畅运行和高效应用。而一款搭载先进硬件配置的13.3寸…

线性代数基础02_矩阵(下)向量

目录 一、矩阵&#xff08;下&#xff09; 1、伴随矩阵 2、逆矩阵 3、初等变换 4、矩阵的标准形 4.1行阶梯形矩阵 4.2简化行阶梯型矩阵 二、向量 1、定义 2、向量的运算 3、矩阵的特征值和特征向量 4、向量的模 5、向量的内积 一、矩阵&#xff08;下&#xff09;…

动态规划-子数组系列——乘积最大子数组

1.题目解析 题目来源&#xff1a;152.乘积最大子数组——力扣 测试用例 2.算法原理 1.状态表示 由于题目给的数组中可以包含负数&#xff0c;因此求最大乘积有两种情况&#xff1a; a.负数乘以最小数得出最大乘积 b.整数乘以最大数得出最大乘积 所以需要两个表分别求出最大最…

Ajax(web笔记)

文章目录 1.Ajax的概念2.Ajax 的作用3.原生Ajax4.Axios4.1Axios的概念4.2Axios入门 1.Ajax的概念 AsynchronousJavaScriptAndXML&#xff0c;异步的JavaScript和XML 2.Ajax 的作用 数据交换:过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互:可以在…

R语言医学数据分析实践-R编程环境的搭建

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 R语言对编程环境的要求不高&#xff0c;可以在多种操作系统平台上…

找寻孤独伤感视频素材的热门资源网站推荐

在抖音上&#xff0c;伤感视频总是能够引起观众的共鸣&#xff0c;很多朋友都在寻找可以下载伤感视频素材的地方。作为一名资深的视频剪辑师&#xff0c;今天我来分享几个提供高清无水印伤感素材的网站&#xff0c;如果你也在苦苦寻找这些素材&#xff0c;不妨看看以下推荐&…

【软件运行类文档】项目试运行方案,试运行计划书(word原件)

一、 试运行目的 &#xff08;一&#xff09; 系统功能、性能与稳定性考核 &#xff08;二&#xff09; 系统在各种环境和工况条件下的工作稳定性和可靠性 &#xff08;三&#xff09; 检验系统实际应用效果和应用功能的完善 &#xff08;四&#xff09; 健全系统运行管理体制&…

RabbitMQ进阶_延迟消息

文章目录 一、 死信交换机和延迟消息1.1、 死信交换机1.2、 延迟消息 二、 DelayExchange插件三、 实现时的优化 在电商的支付业务中&#xff0c;对于一些库存有限的商品&#xff0c;为了更好的用户体验&#xff0c;通常都会在用户下单时立刻扣减商品库存。例如电影院购票、高铁…

How to install Node.js and NPM on CentOS

How to install Node.js and NPM on CentOS Download Node.js 菜鸟教程-Node.js 安装配置 Introduction Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and…

今日指数项目集成SpringSecurity

项目集成SpringSecurity ​ 在第一章我们是基于SpringSecurity、JWT技术实现前后端无状态化认证授权&#xff0c;而我们当前的项目是前后端分离的架构&#xff0c;同样也可借助Security框架和Jwt实现前后端的无状态认证授权操作&#xff1b; 1、项目自定义认证过滤器 1.1 依…

特斯拉Robotaxi发布会2024:自动驾驶未来的开端

引言 2024年10月&#xff0c;特斯拉在洛杉矶举行了一场引发全球科技界高度关注的发布会&#xff0c;主题为“We Robot”。这场发布会展示了特斯拉的最新自动驾驶技术&#xff0c;包括无人驾驶出租车Cybercab和无人驾驶厢式货车Robovan&#xff0c;并且还展示了人形机器人Optim…

D43【python 接口自动化学习】- python基础之函数

day43 装饰器&#xff08;上&#xff09; 学习日期&#xff1a;20241020 学习目标&#xff1a;函数&#xfe63;- 56 装饰器&#xff1a;函数嵌套的定义与调用的区别 学习笔记&#xff1a; 变量作用域 变量读取顺序&#xff1a;local-》enclosed-》global-》builtin # 变量…

c语言经典100例

1.字符串转为数字 #include <stdio.h>int strToInt(char *s) {int num0;int sign1;int step1;if (*s -){sign -1;s;}while (*s > 0&&*s < 9){num num*10(*s-0);step 10;s;}return num*sign; }int main() {char a[10] "-1234";char *s a ;pr…

数据库知识点整理

DDL DDL-数据库操作 show databases ------------ 查看所有数据库 select database(); ----------查看当前数据库 create database 数据库名&#xff1b;---- 创建数据库 use 数据库名&#xff1b; --------------使用数据库 drop database 数据库名&#xff1b;--…

自由学习记录(11)

Surface Effector 2D Platform Effector 2D 向上跳跃穿过天花板的功能 平台效应器不用变Trigger&#xff0c;因为本来就是要有碰撞的 use one way grouping是让所有相关联的碰撞器都可以单面跳墙 默认不勾选&#xff0c;左右两边没有摩擦力和弹力&#xff0c;要自己先设置sid…

poisson过程——随机模拟(Python和R实现)

Python实现 exponential()使用&#xff0c;自动poisson过程实现。 import numpy as np import matplotlib.pyplot as plt# Parameters lambda_rate 5 # rate parameter (events per time unit) T 10 # total time# Generate Poisson process times np.random.exponential(…