Spring Boot 使用日期范围执行搜索

lf5gs5x2  于 2023-05-17  发布在  Spring
关注(0)|答案(1)|浏览(175)

我想使用Sping Boot 实现日期范围搜索。我试过这个:
网址:localhost:8080/users/users?page=0&size=3&createdAt=2023-05-02T04:57:19.83795Z

端点:

@GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
    public Page<UsersResource> getUsersBySearchSpecification(@Valid UserSearchParams params, Pageable pageable)
    {
        Page<UsersResource> list = userService.getUsersBySpecification(params, pageable);
        return list;
    }

UserSearchParams:

@Getter
@Setter
public class UserSearchParams {

    private String param1;

    private Integer param2;

    private List<String> param3;

    @DateTimeFormat(iso = DATE_TIME) 
    LocalDateTime startDate;

    private OffsetDateTime createdAt;
}

搜索功能:

public Page<Users> getUsersBySpecification(UserSearchParams params, Pageable pageable)
    {
        Specification<Users> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (params.getCreatedAt() != null) {
                predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
            }
            if (params.getCreatedAt() != null) {
                predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

    return userRepository.findAll(spec, pageable);
}

搜索功能不起作用。createdAt应该使用什么数据类型?OffsetDateTimeLocalDateTime是更好的选择?
我应该手动解析值2023-05-02T04:57:19.83795Z还是可以依靠Sping Boot 来解析日期?.
此代码是否正确实现:

if (params.getCreatedAt() != null) {
            predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
        }
        if (params.getCreatedAt() != null) {
            predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
        }

或者有更好的方法来选择这个范围?

ftf50wuq

ftf50wuq1#

让我根据我的经验(多个不同的企业项目)逐步回答**。附加说明:我主要使用PostgreSQL作为数据库。

  • 通常使用LocalDateTime。因为使用更方便,所以它没有时区信息。对于数据库,通常timestamp是合适的列类型。
  • Sping Boot 能够将请求参数解析为LocalDateTime类型,而无需显式自定义配置实现。下面是LocalDateTime类型的请求示例:
  • https://localhost:8080/my/endpoint?startDate=2023-01-01T00:30:00.000&endDate=2023-12-31T23:30:00.000
  • https://localhost:8080/my/endpoint?startDate=2023-01-01T00%3A30%3A00.000&endDate=2023-12-31T23%3A30%3A00.000(html解码)

下面是相应的控制器代码:

@GetMapping(value = "/my/endpoint")
    public void myMethod(
            @RequestParam(name = "startDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime startDate,
            @RequestParam(name = "endDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime endDate) {
        return doSearch(startDate, endDate);
    }

但是要小心旧的Spring版本。根据我的经验,它应该从Sping Boot 2.2.X开始工作。***这个想法是有一个比2.1版本更高的JPA实现,因为在2.1版本中没有方便的使用LocalDateTime
更多信息可以在here中找到。

相关问题