【问题标题】:Spring Data JPA : Efficient Way to Invoke Repository Methods with Optional ParametersSpring Data JPA:使用可选参数调用存储库方法的有效方法
【发布时间】:2021-11-11 23:56:34
【问题描述】:

我有下面的Java 11 方法,它由控制器调用,其中ID 是必需的参数,status,version 是可选参数。我不得不编写多个repository 方法来根据这些参数获取记录。我想知道是否有更好/更有效的方法来重构这种方法而无需 if/else 阶梯?

    @Override
    @Transactional(transactionManager = "customTransactionManager")
    public Optional<String> getInformation(UUID id, Status status, Long version) {
        try {
            Preconditions.checkNotNull(id, ID_MUST_BE_NOT_NULL_MSG);
            if (status != null && version != null) {
                return repository.findByIdAndVersionAndStatus(id, version, status);
            } else if (status != null) {
                return repository.findFirstByIdAndStatus(id, status);
            } else if (version != null) {
                return repository.findFirstByIdAndVersion(id, version);
            } else {
                return repository.findFirstByIdOrderByIdDesc(id);
            }
        } catch (Exception e) {
            log.error(e);
            throw new CustomException(MessageFormat.format(PUBLIC_ERROR_MESSAGE, id));
        }
    }

【问题讨论】:

标签: spring spring-boot spring-data-jpa java-11


【解决方案1】:

您可以为此使用Specifications

private Specification<YourEntity> toSpecification(UUID id, Status status, Long version) {
    return (root, query, builder) -> {
        Set<Predicate> predicates = new HashSet<>();
        predicates.add(builder.equal(root.get("id"), id));
        if (status != null) predicates.add(builder.equal(root.get("status"), status));
        if (version != null) predicates.add(builder.equal(root.get("version"), version));
        return builder.and(predicates.toArray(Predicate[]::new));
    };
}

如果您让您的存储库扩展 JpaSpecificationExecutor,您可以像这样使用构建规范对象:

Specification<YourEntity> specification = toSpecification(id, status, version);
Optional<YourEntity> result = repository.findOne(specification);

使用Hibernate Metamodel Generator 时,您也可以写成builder.equal(YourEntity_.id, id) 而不是builder.equal(root.get("id"), id)

【讨论】:

    【解决方案2】:

    除了公认的答案之外,我发现 Query By Examples 更加直观和简单。

    https://www.baeldung.com/spring-data-query-by-example 将是一个好的开始。

    它基本上根据您的 jpa 实体中的非空字段创建一个查询。

    【讨论】:

      猜你喜欢
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      • 2018-09-25
      • 2019-03-25
      • 2014-04-22
      • 1970-01-01
      • 2014-02-02
      相关资源
      最近更新 更多