问题描述
我想编写一个 JPA 存储库查询,该查询可以使用两个可选的查询参数 findBy
和 startDate
endDate
:
开始日期 | 结束日期 | 返回 |
---|---|---|
空 | 空 | 全部 |
空 | 结束日期 | 结束前 |
开始日期 | 空 | 开始后 |
开始日期 | 结束日期 | 开始和结束之间 |
如何简洁地实现?例如,将单个 JPA @Query
方法与可以处理 null
或 Optional<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 的开关编码)