【问题标题】:Search records between two dates using Spring Data JPA native query?使用 Spring Data JPA 原生查询在两个日期之间搜索记录?
【发布时间】:2021-01-08 22:02:51
【问题描述】:

我正在尝试使用 Spring Data Jpa 创建一个端点,以使用户/客户端能够使用我的表中的日期列查找记录的详细信息,但是正在获取的记录只是结束日期之前的记录。

例如,我想要 18 日到 20 日之间的记录,但获取的记录是 18 日和 19 日的记录,即使表中存在该日期(20 日)的记录,也会忽略 20 日的记录。我需要一种方法来检索 18 日和 19 日的记录以及与结束日期有关的记录,在这种情况下是 20 日。任何帮助表示赞赏。

以下是我在 JPA 存储库中使用 JPA 原生查询尝试过的方法。

在第一种方法中,我使用了 BETWEEN 本地查询,但未获取结束日期的记录。这是下面的代码sn-p:

@Query(value = "SELECT * FROM PAYMENT_MASTER WHERE LAST_UPDATED BETWEEN :startDate AND :endDate", nativeQuery = true)
List<PaymentMaster> getAllBetweenDates(@Param("startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDate startDate,
                                       @Param("endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDate endDate);

下面是我尝试过的另一种方法,它给出了与上述方法和以前的方法相同的结果。在这里,我使用了原生查询 GREATER THAN/EQUAL TO AND LESS THAN/EQUAL TO,但仍然没有得到想要的结果。这是存储库中的代码 sn-p:

@Query(value = "SELECT * FROM PAYMENT_MASTER WHERE LAST_UPDATED >= :startDate AND LAST_UPDATED <= :endDate", nativeQuery = true)
List<PaymentMaster> getAllBetweenDates(@Param("startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDate startDate,
                                       @Param("endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDate endDate);

这是来自我的控制器的代码 sn-p:

@PostMapping("/find/date-between")
public ResponseEntity<Object> findPaymentByDate(@RequestBody DateSearcherDto searcherDto) {
    List<PaymentMaster> paymentMasterList = paymentMasterRepository.getAllBetweenDates(searcherDto.getStartDate(), searcherDto.getEndDate());
    List<PaymentMasterDto> resultsDto = new ArrayList<>();
}

更新

请查看我在下面创建的 DateSearcher DTO。


package com.oasis.firsbacklogbackend.dto;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDateTime;

@Data
public class DateSearcherDto {

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME, pattern = "yyyy-MM-dd")
    private LocalDateTime startDate;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME, pattern = "yyyy-MM-dd")
    private LocalDateTime endDate;

}


您的帮助将不胜感激。谢谢。

【问题讨论】:

  • LAST_UPDATED 的类型是什么?本地日期?实例?
  • 这是我在下面的实体类中使用它的最后一个更新字段...谢谢@UpdateTimestamp @Column(name="last_updated") private LocalDateTime lastUpdated;

标签: java spring-boot spring-data-jpa


【解决方案1】:

根据@gtiwari333 的回答,我修改了我的代码,并且能够获得获取所有记录(包括结束日期的记录)的预期结果。以下是为了将来的读者而进行的修改。

我修改后的仓库

    @Query(value = "SELECT * FROM PAYMENT_MASTER WHERE LAST_UPDATED >= :startDate AND LAST_UPDATED <= :endDate", nativeQuery = true)
    List<PaymentMaster> getAllBetweenDates(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);


我修改后的控制器

@PostMapping("/find/date-between")
    public ResponseEntity<Object> findPaymentByDate(@RequestBody DateSearcherDto searcherDto) {

        LocalDateTime start = LocalDateTime.of(LocalDate.from(searcherDto.getStartDate()), LocalTime.of(0, 0, 0));
        LocalDateTime end = LocalDateTime.of(LocalDate.from(searcherDto.getEndDate()), LocalTime.of(23, 59, 59));

        List<PaymentMaster> paymentMasterList =
                paymentMasterRepository.getAllBetweenDates(start, end);


我的 DateSearcher Dto 修改:

package com.oasis.firsbacklogbackend.dto;

import lombok.Data;

import java.time.LocalDate;

@Data
public class DateSearcherDto {

    private LocalDate startDate;

    private LocalDate endDate;

}



这就是我解决问题的方法。通过这些修改,它就像魔术一样工作......谢谢。

【讨论】:

    【解决方案2】:

    如果您要进行日期/时间比较,则必须将下限设置为清晨,将上限设置为深夜。另外,更新您的查询以采用LocalDateTime

    @Query(value = "SELECT * FROM PAYMENT_MASTER WHERE LAST_UPDATED >= :startDate AND LAST_UPDATED <= :endDate", nativeQuery = true)
    List<PaymentMaster> getAllBetweenDates(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);
    

    为您服务:

    LocalDateTime start = LocalDateTime.of(searcherDto.getStartDate(), LocalTime.of(0, 0, 0));
    LocalDateTime end = LocalDateTime.of(searcherDto.getEndDate(), LocalTime.of(23, 59, 59));
    
    paymentMasterRepository.getAllBetweenDates(start, end);
    

    【讨论】:

    • 感谢您的回复。我尝试了您的解决方案,但出现如下错误: JSON 解析错误:无法从字符串“2020-09-21”反序列化 java.time.LocalDateTime 类型的值:无法反序列化 java.time.LocalDateTime: (java.time.format. DateTimeParseException) 无法在索引 10 处解析文本“2020-09-21”;
    • (通过参考链:com.oasis.firsbacklogbackend.dto.DateSearcherDto["startDate"]) 我的 Dto 中出现错误,我仅为 startDate 和 endDate 创建。请检查问题对于我创建的完整 DateSearcherDto 类。
    • 您能否更新您的 DTO 以使用 LocalDate 而不是 LocalDateTime 。 'yyyy-MM-dd' 也是默认格式,你不需要指定。
    • snippi.com/s/phne13a 见此工作示例
    • 在我将 dto 更新为 LocalDate 而不是 LocalDateTime 后,它现在可以正常工作了...感谢一百万 @gtiwari。
    猜你喜欢
    • 2020-04-17
    • 1970-01-01
    • 2013-12-23
    • 2016-05-16
    • 1970-01-01
    • 2020-04-17
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多