JPA 查询以在可选的开始日期和结束日期之前、之后和之间进行过滤
JPA query to filter before, after and between optional start and end dates
我想编写一个 JPA 存储库查询,可以 findBy
使用两个可选查询参数,startDate
和 endDate
:
startDate
endDate
Return
null
null
All
null
endDate
Before End
startDate
null
After Start
startDate
endDate
Between Start and End
如何简洁地实现?例如,使用带有可以处理 null
或 Optional<Date>
参数的 SQL 语句的单个 JPA @Query
方法?
编辑:我正在使用 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
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 开关编码归功于此)
我想编写一个 JPA 存储库查询,可以 findBy
使用两个可选查询参数,startDate
和 endDate
:
startDate | endDate | Return |
---|---|---|
null | null | All |
null | endDate | Before End |
startDate | null | After Start |
startDate | endDate | Between Start and End |
如何简洁地实现?例如,使用带有可以处理 null
或 Optional<Date>
参数的 SQL 语句的单个 JPA @Query
方法?
编辑:我正在使用 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
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 开关编码归功于此)