如何将 LocalDateTime 提供给 jpa/hibernate 查询?
Posted
技术标签:
【中文标题】如何将 LocalDateTime 提供给 jpa/hibernate 查询?【英文标题】:How to supply LocalDateTime to a jpa/hibernate query? 【发布时间】:2020-06-04 01:35:45 【问题描述】:我正在我的@RepositoryRestResource 中构建一个查询
查询如下所示:
@Query("Select DISTINCT comp from InsuranceCompany comp " +
"LEFT JOIN comp.orders ord " +
"wHERE ord.invoiced = false " +
"and (:date is null or :date >= ord.completionTime)"
)
public Page<InsuranceCompany> method(LocalDateTime date, Pageable pageable);
但它会引发以下异常
Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2020-02-14T15:50:24'
当我调用终点时:
GET /method?date=2020-02-14T15:50:24
【问题讨论】:
【参考方案1】:Spring 默认无法将 REST 参数转换为 LocalDateTime。您需要提供有关日期格式的信息,在参数级别使用 @DateTimeFormat 注释,或使用 DateTimeFormatterRegistrar 全局提供。
这篇文章解释了两种选择:https://www.baeldung.com/spring-date-parameters
【讨论】:
【参考方案2】:用 @DateTimeFormat
标记它,让 Spring 正确转换它:
public Page<InsuranceCompany> method(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime date,
Pageable pageable);
【讨论】:
【参考方案3】:选项 1:为所有 Spring Boot App REST Endpoints 全局设置日期/时间格式
您可以全局配置 spring 以对您的 REST 端点使用特定的日期/日期时间格式。建议您使用默认的 Jackson 来处理 JSON 映射,您可以创建一个配置类,如下所示在其中设置格式:
@Configuration
public class DateTimeSerializationConfiguration implements Jackson2ObjectMapperBuilderCustomizer
private static final DateTimeFormatter DATE_FORMATTER = ISO_LOCAL_DATE;
private static final DateTimeFormatter DATE_TIME_FORMATTER = ISO_DATE_TIME;
private static final DateTimeFormatter TIME_FORMATTER = ofPattern("HH:mm");
@Bean
public Formatter<LocalDate> localDateFormatter()
return new Formatter<LocalDate>()
@Override
public LocalDate parse(String text, Locale locale)
return LocalDate.parse(text, DATE_FORMATTER);
@Override
public String print(LocalDate object, Locale locale)
return DATE_FORMATTER.format(object);
;
@Bean
public Formatter<LocalDateTime> localDateTimeFormatter()
return new Formatter<LocalDateTime>()
@Override
public LocalDateTime parse(String text, Locale locale)
return LocalDateTime.parse(text, DATE_TIME_FORMATTER);
@Override
public String print(LocalDateTime object, Locale locale)
return DATE_TIME_FORMATTER.format(object);
;
@Bean
public Formatter<LocalTime> localTimeFormatter()
return new Formatter<LocalTime>()
@Override
public LocalTime parse(String text, Locale locale)
return LocalTime.parse(text, TIME_FORMATTER);
@Override
public String print(LocalTime object, Locale locale)
return TIME_FORMATTER.format(object);
;
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder)
jacksonObjectMapperBuilder.serializers(
new LocalDateSerializer(DATE_FORMATTER),
new LocalDateTimeSerializer(DATE_TIME_FORMATTER),
new LocalTimeSerializer(TIME_FORMATTER));
jacksonObjectMapperBuilder.deserializers(
new LocalDateDeserializer(DATE_FORMATTER),
new LocalDateTimeDeserializer(DATE_TIME_FORMATTER),
new LocalTimeDeserializer(TIME_FORMATTER));
然后,您可以像这样创建控制器方法:
@RestController
public class BookingController
private final YourService yourService;
@Autowired
public BookingController(YourService yourService)
this.yourService = yourService;
@GetMapping("/your/api/endpoint")
public YourObject yourControllerMethod(@RequestParam LocalDate date, Pageable pageable)
return yourService.yourServiceMethod(date, pageable);
// Or: with LocalDateTime
@GetMapping("/your/api/endpoint")
public YourObject yourControllerMethod(@RequestParam LocalDateTime dateTime, Pageable pageable)
return yourService.yourServiceMethod(dateTime, pageable);
选项 2:分别为每个 REST Endpoint 设置日期/时间格式
如果您希望单独为每个端点设置格式,则必须使用 @DateTimeFormat
注释请求参数并指定预期格式。下面的示例显示了有关如何完成此操作的不同示例:
@RestController
public class BookingController
private final YourService yourService;
@Autowired
public BookingController(YourService yourService)
this.yourService = yourService;
@GetMapping("/your/api/endpoint")
public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, Pageable pageable)
return yourService.yourServiceMethod(date, pageable);
// Or: with LocalDateTime
@GetMapping("/your/api/endpoint")
public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateTime, Pageable pageable)
return yourService.yourServiceMethod(dateTime, pageable);
// Or: with your custom pattern
@GetMapping("/your/api/endpoint")
public YourObject yourControllerMethod(@RequestParam @DateTimeFormat(pattern = "dd.MM.yyyy") LocalDate date, Pageable pageable)
return yourService.yourServiceMethod(date, pageable);
【讨论】:
以上是关于如何将 LocalDateTime 提供给 jpa/hibernate 查询?的主要内容,如果未能解决你的问题,请参考以下文章
vue js java LocalDateTime时间展示问题