如何配置LocalDateTime转LocalDate的转换器以实现当日菜单查询
可行实现方案
1. 调整Controller层参数类型
把接口入参从LocalDateTime改为LocalDate,调整日期格式化规则和默认值即可支持用户传不带时间的日期参数:
@GetMapping("/all-menu-of-the-day") public List<Restaurant> findAllByMenuOfDay( @RequestParam(defaultValue = "#{T(java.time.LocalDate).now()}") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) { return restaurantService.findAllByMenuOfDay(date); }
2. 调整Repository查询逻辑
因为数据库存储的是LocalDateTime带时间的类型,有两种常用查询写法可选:
方案A:时间区间查询(兼容性更好,性能更高)
把传入的LocalDate转成当天的起始、结束时间点做区间匹配,适配所有JPA版本:
Repository层代码:
@Query("SELECT DISTINCT r from Restaurant r JOIN FETCH r.menu m where m.updatedAt BETWEEN :startOfDay AND :endOfDay") List<Restaurant> findAllByMenuOfDay(@Param("startOfDay") LocalDateTime startOfDay, @Param("endOfDay") LocalDateTime endOfDay);
Service层补充时间转换逻辑:
public List<Restaurant> findAllByMenuOfDay(LocalDate date) { LocalDateTime start = date.atStartOfDay(); LocalDateTime end = date.plusDays(1).atStartOfDay(); return restaurantRepository.findAllByMenuOfDay(start, end); }
方案B:JPQL类型转换匹配(代码更简洁)
如果使用Hibernate 5.2及以上版本,支持直接在JPQL里做日期类型转换,无需额外转换逻辑:
@Query("SELECT DISTINCT r from Restaurant r JOIN FETCH r.menu m where CAST(m.updatedAt AS LocalDate) = :date") List<Restaurant> findAllByMenuOfDay(@Param("date") LocalDate date);
直接传入Controller拿到的LocalDate参数即可调用。
注意事项
- 确保应用、JPA配置、数据库的时区保持一致,避免日期转换出现偏差
- 如果业务侧菜单更新频率是按日更新,可以考虑在表中冗余存储
LocalDate类型的更新日期字段,查询性能会更优
内容的提问来源于stack exchange,提问作者Kanari Himawari
相关产品推荐
相关产品推荐

