【发布时间】:2020-05-31 06:42:19
【问题描述】:
我有以下存储库:
@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 过滤实体,这两个参数在数据库中永远不是nulls,但可以通过构造函数传递(用于搜索的参数是可选的)。
当null 作为可选参数传递时,命名查询出现问题,JpaReposotory 使用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 个参数实现完全相同的过滤。
【问题讨论】:
标签: java spring spring-boot spring-data-jpa optional