Spring Data JPA-忽略空参数的命名查询

我有以下存储库:

@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-

pluginOptional<Long>用作可选请求参数(基础服务也使用相同的参数):

ResponseEntity<List<Entity>> entities(Optional<Long> firstId, Optional<Long> secondId);

我想过滤基于参数实体firstIdsecondId它们从不null■在数据库中,但可以通过构造函数(用于搜索的可选参数)进行传递。

这个问题是与命名查询时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 忽略参数,如果它具有空值并且创建了票据DATAJPA-209。

只要问题已经存在了将近3年,而故障单可以追溯到2012年,我想问一下是否存在一种更舒适,更通用的方法来避免处理Optional和复制存储库方法的开销。2个此类参数的解决方案看起来可以接受,但是我想对4-5个参数实施完全相同的过滤。

回答:

您需要Specification像这样的实用程序类

public class EntitySpecifications {

public static Specification<Entity> firstIdEquals(Optional<Long> firstId) {// or Long firstId. It is better to avoid Optional method parameters.

return (root, query, builder) ->

firstId.isPresent() ? // or firstId != null if you use Long method parameter

builder.equal(root.get("firstId"), firstId.get()) :

builder.conjunction(); // to ignore this clause

}

public static Specification<Entity> secondIdEquals(Optional<Long> secondId) {

return (root, query, builder) ->

secondId.isPresent() ?

builder.equal(root.get("secondId"), secondId.get()) :

builder.conjunction(); // to ignore this clause

}

}

然后你EntityRepository必须扩展JpaSpecificationExecutor

@Repository

public interface EntityRepository

extends JpaRepository<Entity, Long>, JpaSpecificationExecutor<Entity> {

}

用法:

@Service

public class EntityService {

@Autowired

EntityRepository repository;

public List<Entity> getEntities(Optional<Long> firstId, Optional<Long> secondId) {

Specification<Entity> spec =

Specifications.where(EntitySpecifications.firstIdEquals(firstId)) //Spring Data JPA 2.0: use Specification.where

.and(EntitySpecifications.secondIdEquals(secondId));

return repository.findAll(spec);

}

}

以上是 Spring Data JPA-忽略空参数的命名查询 的全部内容, 来源链接: utcz.com/qa/419734.html

回到顶部