{ "assembleOutputTaskId": "6dad3dcb191b63a8aadc3360cad027d7", "outputMaterialList": [ { "assembleOutputTaskId": "6dad3dcb191b63a8aadc3360cad027d7", "branchCompanyId": "55a548278fbb4f84bfa653be58994303", "branchCompanyName": "宽体车", "companyId": "6ec7b365dd5e4caeab299031c8bd1bfc", "consumeProcedureNo": null, "creatorId": "6b6357842ccc43b29652a74ecf23ad3f", "creatorName": "何继虎", "deptId": null, "gmtCreate": "2025-06-06 16:31:11", "gmtModified": "2025-06-06 16:31:11", "id": "02b9ebe8ec33831dc343126d3e4c7ae6", "isDel": 0, "isKeyComponent": null, "isLackMaterials": 1, "keyComponentSnCode": null, "lackItemNum": null, "materialCode": "00014material", "materialName": "荣耀手机屏幕", "modifiedId": "6b6357842ccc43b29652a74ecf23ad3f", "modifiedName": "何继虎", "securityLevel": null, "stationCode": null, "stationName": null, "uid": "02b9ebe8ec33831dc343126d3e4c7ae6", "workProcedureName": null } ] } 这样的数据,assembleOutputTaskId是key,outputMaterialList是value,用redisTemplate应该怎么存
时间: 2025-06-07 21:29:48 浏览: 11
<think>我们使用RedisTemplate存储JSON数据时,需要配置合适的序列化器。根据引用[1],我们可以看到使用Jackson2JsonRedisSerializer将对象序列化为JSON存储的示例。但是注意:引用中的代码在每次操作前都设置序列化器,这在实际应用中通常不是最佳做法(通常会在配置类中全局配置)。不过,如果只是针对特定操作临时设置,也可以这样用。对于问题:将assembleOutputTaskId作为key,outputMaterialList(JSON数据结构)作为value存储到Redis中。步骤:1.确定key和value的类型:key是字符串,value是一个List(或者自定义对象)的JSON表示。2.选择合适的序列化器:对于值,我们可以使用Jackson2JsonRedisSerializer。对于键,通常使用StringRedisSerializer。3.存储操作:使用opsForValue().set方法。注意:为了避免每次操作都设置序列化器,我们一般建议在RedisTemplate的配置中设置好。但为了回答直接,这里给出两种方式:全局配置和临时设置。方式一(推荐):在Spring配置类中配置好RedisTemplate的序列化方式(通常是一次性配置),然后在代码中直接使用。方式二:在每次存储前临时设置序列化器(如引用[1]所示),但这样效率较低且容易出错。由于问题中没有说明全局配置的情况,我们按照引用[1]的方式,在代码中临时设置序列化器(仅针对该操作)。但是注意:如果我们的RedisTemplate之前配置了其他序列化器(比如默认的JdkSerializationRedisSerializer),那么临时修改序列化器可能会影响其他操作。所以,更安全的做法是在一个独立的RedisTemplate实例上操作,或者全局配置。这里我们假设允许临时设置,并且outputMaterialList是一个Java对象(比如List<Material>)。具体步骤:a.创建key的序列化器(字符串)和value的序列化器(JSON)。b.设置RedisTemplate的key和value的序列化器。c.执行set操作。但是,注意:RedisTemplate是线程安全的,但是修改序列化器可能会影响到其他线程。所以,我们通常不会在运行时改变序列化器。因此,我们考虑使用两个RedisTemplate实例?或者,我们可以创建一个新的操作序列。实际上,更好的方式是:在配置类中配置两个RedisTemplate,一个用于普通字符串操作,一个用于JSON操作。由于问题中要求使用JSON存储,我们假设已经有一个配置好的RedisTemplate,其value的序列化器是Jackson2JsonRedisSerializer。但为了演示,我们按照引用[1]的方式,在代码中临时设置。但请注意:在并发环境下,修改RedisTemplate的序列化器可能会导致不可预知的问题。所以,这里给出一种更安全的方式:使用一个独立的RedisTemplate实例(或者使用同一配置的多个实例),并在配置时就设置好序列化器。如果一定要在代码中临时设置,可以使用execute方法在Connection上操作,但那样更复杂。因此,我们折中:如果全局没有配置,那么我们可以在方法内部创建一个新的RedisTemplate实例,并设置好序列化器,然后执行操作。但这样每次调用都创建RedisTemplate开销较大。综合考虑,我推荐在应用启动时配置好RedisTemplate。下面,我们先给出一个在代码中临时设置序列化器的方式(注意:这种方式在多线程环境下不安全,仅作演示),然后给出全局配置的示例。方式一(临时设置序列化器,不推荐在生产环境使用):```java//假设assembleOutputTaskId是字符串Stringkey=assembleOutputTaskId;//outputMaterialList是一个Java对象(比如List<OutputMaterial>)Objectvalue=outputMaterialList;//创建JSON序列化器Jackson2JsonRedisSerializer<Object>serializer=newJackson2JsonRedisSerializer<>(Object.class);//配置ObjectMapper(可选,如果需要自定义JSON特性)//这里省略,如果需要,可以设置//获取RedisTemplate并设置序列化器//注意:这里我们假设redisTemplate已经注入//临时设置key和value的序列化器redisTemplate.setKeySerializer(newStringRedisSerializer());redisTemplate.setValueSerializer(serializer);//存储redisTemplate.opsForValue().set(key,value);//如果需要设置过期时间,可以这样://redisTemplate.opsForValue().set(key,value,30,TimeUnit.MINUTES);```方式二(推荐,在配置类中全局配置一个用于JSON存储的RedisTemplate):1.创建配置类,定义一个RedisTemplateBean,用于JSON序列化。2.在需要的地方注入这个RedisTemplate。配置类示例:```java@ConfigurationpublicclassRedisConfig{@BeanpublicRedisTemplate<String,Object>jsonRedisTemplate(RedisConnectionFactoryconnectionFactory){RedisTemplate<String,Object>template=newRedisTemplate<>();template.setConnectionFactory(connectionFactory);//使用StringRedisSerializer来序列化和反序列化redis的keytemplate.setKeySerializer(newStringRedisSerializer());//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的valueJackson2JsonRedisSerializer<Object>serializer=newJackson2JsonRedisSerializer<>(Object.class);//配置ObjectMapper(可选,根据需求)ObjectMappermapper=newObjectMapper();mapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),ObjectMapper.DefaultTyping.NON_FINAL);serializer.setObjectMapper(mapper);template.setValueSerializer(serializer);//设置hashkey和value的序列化模式template.setHashKeySerializer(newStringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();returntemplate;}}```然后在服务类中注入:```java@AutowiredprivateRedisTemplate<String,Object>jsonRedisTemplate;```存储操作:```javajsonRedisTemplate.opsForValue().set(assembleOutputTaskId,outputMaterialList);```这样,存储的值将会是JSON格式。注意:使用Object.class作为Jackson2JsonRedisSerializer的泛型,可以接受任何对象,但是反序列化时需要知道具体类型,或者配置ObjectMapper激活默认类型信息(如上面的activateDefaultTyping),这样JSON中会包含类型信息,但会增加一些存储空间。如果不希望存储类型信息,可以将ObjectMapper的激活默认类型去掉,但是在读取的时候需要指定具体的类型。所以,根据你的需求,如果outputMaterialList是同一个类型,你可以在创建Jackson2JsonRedisSerializer时指定具体的类型,例如:```javaJackson2JsonRedisSerializer<OutputMaterialList>serializer=newJackson2JsonRedisSerializer<>(OutputMaterialList.class);```这样就不需要类型信息,但反序列化时也必须使用相同的类型。综上所述,推荐使用全局配置的RedisTemplate,并在序列化器中使用具体的类型(如果知道类型的话)以避免类型安全问题。因此,针对问题,如果使用全局配置的jsonRedisTemplate,代码非常简单:```javajsonRedisTemplate.opsForValue().set(assembleOutputTaskId,outputMaterialList);```如果设置过期时间:```javajsonRedisTemplate.opsForValue().set(assembleOutputTaskId,outputMaterialList,30,TimeUnit.MINUTES);```引用[1]中还提到finally块中释放连接,在SpringDataRedis中,通常不需要手动释放连接,因为RedisTemplate会自动管理连接。所以不需要调用`RedisConnectionUtils.unbindConnection`。所以,最终代码:```javatry{jsonRedisTemplate.opsForValue().set(assembleOutputTaskId,outputMaterialList);//如果需要过期时间,使用://jsonRedisTemplate.opsForValue().set(assembleOutputTaskId,outputMaterialList,30,TimeUnit.MINUTES);}catch(Exceptione){//异常处理e.printStackTrace();}```注意:这里jsonRedisTemplate是我们自己配置的用于JSON序列化的RedisTemplate。如果不想单独配置一个RedisTemplate,也可以使用StringRedisTemplate,然后自己将对象转换为JSON字符串存储,这样也是常见做法:```java//注入StringRedisTemplate@AutowiredprivateStringRedisTemplatestringRedisTemplate;//将对象转为JSON字符串ObjectMapperobjectMapper=newObjectMapper();Stringjson=objectMapper.writeValueAsString(outputMaterialList);stringRedisTemplate.opsForValue().set(assembleOutputTaskId,json);```这种方式更直接,但是需要手动转换。根据需求选择。</think>
要将 `assembleOutputTaskId` 作为 key 和 `outputMaterialList`(JSON 数据结构)作为 value 存储到 Redis 中,可以通过配置 `Jackson2JsonRedisSerializer` 实现对象到 JSON 的自动转换。以下是具体实现步骤:
---
### 1. **全局配置 RedisTemplate(推荐)**
在 Spring Boot 配置类中全局配置 JSON 序列化器:
```java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> jsonRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// Key 使用字符串序列化
template.setKeySerializer(new StringRedisSerializer());
// Value 使用 JSON 序列化
Jackson2JsonRedisSerializer<Object> serializer =
new Jackson2JsonRedisSerializer<>(Object.class);
// 配置 ObjectMapper(可选)
ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
return template;
}
}
```
---
### 2. **存储数据**
在业务代码中直接存储对象(自动序列化为 JSON):
```java
@Autowired
private RedisTemplate<String, Object> jsonRedisTemplate;
public void saveData(String assembleOutputTaskId, List<OutputMaterial> outputMaterialList) {
// 存储数据(无过期时间)
jsonRedisTemplate.opsForValue().set(assembleOutputTaskId, outputMaterialList);
// 或存储并设置过期时间(例如 30 分钟)
jsonRedisTemplate.opsForValue().set(
assembleOutputTaskId,
outputMaterialList,
30,
TimeUnit.MINUTES
);
}
```
> **关键点说明**:
> - `jsonRedisTemplate` 会自动将 Java 对象转换为 JSON 字符串存储
> - `OutputMaterial` 需要是**可序列化**的 Java 类(例如有 getter/setter)
> - 通过 `set(key, value, timeout, unit)` 可设置过期时间[^1]
---
### 3. **读取数据**
反序列化 JSON 为 Java 对象:
```java
public List<OutputMaterial> getData(String assembleOutputTaskId) {
return (List<OutputMaterial>) jsonRedisTemplate.opsForValue().get(assembleOutputTaskId);
}
```
---
### 4. **验证效果**
```java
// 存储
List<OutputMaterial> materials = Arrays.asList(
new OutputMaterial("item1", 10),
new OutputMaterial("item2", 20)
);
saveData("task_123", materials);
// 读取
List<OutputMaterial> result = getData("task_123");
System.out.println(result); // 输出反序列化后的对象
```
**Redis 中存储效果**:
```bash
> GET task_123
[
{
"materialId": "item1",
"quantity": 10
},
{
"materialId": "item2",
"quantity": 20
}
]
```
---
### 注意事项
1. **类型安全**:
- 反序列化时需明确类型(如 `(List<OutputMaterial>)`)
- 或改用 `TypeReference`:
```java
Object value = jsonRedisTemplate.opsForValue().get(key);
List<OutputMaterial> list = objectMapper.convertValue(value,
new TypeReference<List<OutputMaterial>>(){});
```
2. **配置优化**:
- 全局配置避免每次操作设置序列化器[^1]
- 自定义 `ObjectMapper` 处理复杂类型(如 LocalDateTime)
3. **连接管理**:
- Spring Data Redis 会自动管理连接,**无需**手动调用 `unbindConnection()`[^1]
---
阅读全文
相关推荐



















