Spring Data with Redis:如何使用不同的 LocalDateTime 格式或不同的转换器?

Posted

技术标签:

【中文标题】Spring Data with Redis:如何使用不同的 LocalDateTime 格式或不同的转换器?【英文标题】:Spring Data with Redis: How do I use a different LocalDateTime format or a different convertor? 【发布时间】:2021-12-24 17:04:42 【问题描述】:

我的数据库中有 date 字段的数据,格式如下:2021-09-21 11:25:36。 Redis 字段的类型为 TEXT。

当我尝试从数据库中读取 date 字段中的数据时,出现以下异常:

Failed to convert from type [byte[]] to type [java.time.LocalDateTime] for value '50, 48, 50, 49, 45, 48, 57, 45, 50, 49, 32, 49, 49, 58, 50, 53, 58, 51, 54'; nested exception is java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [byte[]] to type [java.time.LocalDateTime] for value '50, 48, 50, 49, 45, 48, 57, 45, 50, 49, 32, 49, 49, 58, 50, 53, 58, 51, 54'; nested exception is java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
(...)
Caused by: java.time.format.DateTimeParseException: Text '2021-09-21 11:25:36' could not be parsed at index 10
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2050)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:493)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:478)
    at org.springframework.data.redis.core.convert.Jsr310Converters$BytesToLocalDateTimeConverter.convert(Jsr310Converters.java:113)
    at org.springframework.data.redis.core.convert.Jsr310Converters$BytesToLocalDateTimeConverter.convert(Jsr310Converters.java:108)
    at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    ... 142 more

如何为我的实体中的该字段分配不同的转换器或注释我的 LocalDateTime 格式与预期的不同?我目前的假设是问题在于日期和时间之间缺少“T”,但我几乎不可能更改数据库中的数据。

【问题讨论】:

我认为这会有所帮助***.com/questions/29956175/… 【参考方案1】:

可以使用Jackson json格式com.fasterxml.jackson.annotation.JsonFormat

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime timestamp;

【讨论】:

我认为这仅适用于 JSON 序列化,所以在我的情况下它不起作用,但我刚刚发布了解决方案 :) 感谢您的帮助! 它适用于mongo、sql和redis的spring-data,我一直在使用它。【参考方案2】:

稍后我自己使用 RedisCustomConverters 找到了答案:

这个 bean 是必需的:

    @Bean
    public RedisCustomConversions redisCustomConversions(BytesToLocalDateTimeConverter bytesToLocalDateTimeConverter) 
        return new RedisCustomConversions(List.of(bytesToLocalDateTimeConverter));
    

结合这个自定义转换器:

@Component
@ReadingConverter
public class BytesToLocalDateTimeConverter implements Converter<byte[], LocalDateTime> 

    @Override
    public LocalDateTime convert(final byte[] source) 
        return LocalDateTime.parse(new String(source), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    

【讨论】:

以上是关于Spring Data with Redis:如何使用不同的 LocalDateTime 格式或不同的转换器?的主要内容,如果未能解决你的问题,请参考以下文章

Spring-data-redis + Lettuce 如何使用 Pipeline

如何在 Spring Data JPA 中使用 CTE 表达式 WITH 子句

如何使用 Spring Data Redis 为过期键启用键空间通知

如何在过期事件中访问spring data redis store对象?

Spring Session With Redis - HttpSession (Quick Start)

Spring Boot && Spring Cloud系列在spring-data-Redis中如何使用切换库