尚硅谷redis97集答疑 springboot整合redis之RedisTemplate-下集 补充

        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`,如下所示:


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 格式存储。例如:


"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` 来处理值的序列化和反序列化:

 修改配置


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`


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` 存储和读取中文数据


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);
    }
}
```

 测试


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 中存储的数据将是这样的:


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


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

 总结

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

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值