我有以下代码库:
@Repository
public interface EntityRepository extends JpaRepository<Entity, Long> {
List<Entity> findAllByFirstId(Long firstId);
List<Entity> findAllBySecondId(Long secondId);
List<Entity> findAllByFirstIdAndSecondId(Long firstId, Long secondId);
}
使用io.swagger:swagger-codegen-maven-plugin
生成的接口实现构造器,使用Optional<Long>
作为可选请求参数(底层服务也使用相同的参数):
ResponseEntity<List<Entity>> entities(Optional<Long> firstId, Optional<Long> secondId);
我希望您能根据参数
firstId
和secondId
来筛选实体,这些参数在数据库中从不为null
,但可以通过构造函数传递(搜索参数是可选的)。问题出现在命名查询时,如果将
null
作为可选参数传递,则JpaRepository
将使用null
作为搜索数据库的条件。我不想这样,只要参数为null
,就忽略它作为过滤器的作用。我的解决方案基于
Optional
:public List<Entity> entities(Optional<Long> firstId, Optional<Long> secondId) {
return firstId
.or(() -> secondId)
.map(value -> {
if (firstId.isEmpty()) {
return entityRepository.findAllBySecondId(value);
}
if (secondId.isEmpty()) {
return entityRepository.findAllByFirstId(value);
}
return entityRepository.findAllByFirstIdAndSecondId(
firstId.get(), secondId.get());
})
.orElse(entityRepository.findAll())
.stream()
.map(...) // Mapping between DTO and entity. For sake of brevity
// I used the same onject Entity for both controler and repository
// as long as it not related to the question
.collect(Collectors.toList());
}
这个问题已经被问过了:Spring Data - ignore parameter if it has a null value,并且创建了一个票据DATAJPA-209。 既然这个问题几乎是3年前的了,而且票据也追溯到2012年,我想问问是否存在更舒适和通用的方法来避免处理
Optional
和重复存储库方法的开销。对于2个这样的参数,解决方案似乎是可接受的,但是我想为4-5个参数实现完全相同的过滤。