JPA 查询以使用 Postgres 过滤可选的开始日期和结束日期之前、之后和之间

问题描述

我想编写一个 JPA 存储库查询,该查询可以使用两个可选的查询参数 findBystartDate endDate

开始日期 结束日期 返回
全部
结束日期 结束前
开始日期 开始后
开始日期 结束日期 开始和结束之间

如何简洁地实现?例如,将单个 JPA @Query 方法与可以处理 nullOptional<Date> 参数的 sql 语句一起使用?

编辑:我使用的是 Postgresql 13。

解决方法

您可以使用以下查询来实现此目的。我可以自由地使用 <=>=,但当然您可以选择 <> 或两者之一。这个想法是为了给你一个功能正常的查询。

@Query("SELECT m FROM MyObject m WHERE (:beforeDate is null or m.beforeDate >= :beforeDate) and (:afterDate is null or m.afterDate <= :afterDate)")
List<MyObject> findByDateBetween(Date beforeDate,Date afterDate);
,

这是一个使用 4 种方法和一个开关的简单解决方案。它很笨重,但它有效。如果需要实现更复杂的 JPQL 或 SQL 查询,这种方法会变得特别冗长,因为需要复制 4 个 Repository 方法和查询。

存储库

@Repository
public interface MyRepository extends JpaRepository<MyObject> {
  List<MyObject> findByDateBetween(Date beforeDate,Date afterDate);
  List<MyObject> findByDateBefore(Date beforeDate);
  List<MyObject> findByDateAfter(Date afterDate);
  List<MyObject> findAll();

服务

public List<MyObject> search(Date startDate,Date endDate) {
  int i = (startDate!=null ? 1 : 0) | (endDate!=null ? 2 : 0);
  switch(i) {
    case 0:
      return repository.findAll();
    case 1:
      return repository.findByDateAfter(startDate);
    case 2:
      return repository.findByDateBefore(endDate);
    case 3:
      return repository.findByDateBetween(startDate,endDate);
  }
}

(感谢 Marc Gravell 的这个 answer 的开关编码)