使用JpaRepository进行SQL查询:如何仅基于年,月和日来过滤LocalDateTime?

时间:2019-05-13 20:10:57

标签: java sql sql-server jpa spring-data-jpa

我有一个实体“ Show”,它具有一个名为“ start”的LocalDateTime变量:

public class Show {
    //--other code---
    @Column(nullable = false)
    private LocalDateTime start;
    //--other code---
}

我只想根据年,月和日从数据库中选择,而忽略小时和分钟。

我当前的查询是:

@Query(value = "SELECT * FROM show s WHERE s.event_id = :eventId 
AND DATEPART(year, s.start) = DATEPART(year, :dateSearch) 
AND DATEPART(month, s.start) = DATEPART(month, :dateSearch) 
AND DATEPART(day, s.start) = DATEPART(day, :dateSearch)", nativeQuery = true)
Page<Show> findAllFiltered(@Param("eventId") Long eventId, @Param("dateSearch") LocalDateTime dateSearch, Pageable page);

当我尝试执行该查询时,出现以下错误消息,显示500错误代码:

  

“无法准备语句;嵌套的异常是org.hibernate.exception.GenericJDBCException:无法准备语句”

编辑:使代码块中的查询更易于阅读

1 个答案:

答案 0 :(得分:0)

我建议您更改为使用日期/时间范围,而不要使用单个值。如果表恰好在event_id, start

上有一个索引,那在查询中也会有更好的表现。

类似这样的东西:

@Query(value = "SELECT *" +
                " FROM show s" +
               " WHERE s.event_id = :eventId" +
                 " AND s.start >= :startDate" +
                 " AND s.start < :endDate", nativeQuery = true)
Page<Show> findAllFiltered(@Param("eventId") Long eventId,
                           @Param("startDate") LocalDateTime startDate,
                           @Param("endDate") LocalDateTime endDate,
                           Pageable page);

请注意,endDate是互斥的,这与Java中所有范围操作最常见的情况一样。

然后,如果需要,您可以添加一个辅助方法:

Page<Show> findAllFiltered(@Param("eventId") Long eventId,
                           @Param("dateSearch") LocalDateTime dateSearch,
                           Pageable page) {
    LocalDateTime startDate = dateSearch.truncatedTo(ChronoUnit.DAYS);
    LocalDateTime endDate = startDate.plusDays(1);
    return findAllFiltered(eventId, startDate, endDate, page);
}