0

我正在使用 SpringBoot 2.3.1 和 Spring Data 来访问 PostgreSQL。我有以下简单的控制器:

@RestController
public class OrgsApiImpl implements OrgsApi {
    @Autowired
    Orgs repository;

    @Override
    public ResponseEntity<List<OrgEntity>> listOrgs(@Valid Optional<Integer> pageLimit,
        @Valid Optional<String> pageCursor, @Valid Optional<List<String>> domainId,
        @Valid Optional<List<String>> userId) {

        List<OrgEntity> orgs;

        if (domainId.isPresent() && userId.isPresent()) {
            orgs = repository.findAllByDomainIdInAndUserIdIn(domainId.get(), userId.get());
        } else if (domainId.isPresent) {
            orgs = repository.findAllByDomainIdIn(domainId.get());
        } else if (userId.isPresent()) {
            orgs = repository.findAllByUserIdIn(userId.get());
        } else {
            orgs = findAll();
        }

        return ResponseEntity.ok(orgs);
    }
}

还有一个简单的 JPA 存储库:

public interface Orgs extends JpaRepository<OrgEntity, String> {
    List<OrgEntity> findAllByDomainIdIn(List<String> domainIds);

    List<OrgEntity> findAllByUserIdIn(List<String> userIds);

    List<OrgEntity> findAllByDomainIdInAndUserIdIn(List<String> domainIds, List<String> userIds);
}

上面的代码有几个明显的问题:

  1. 如果查询参数的数量会增长,那么这个 if 增长非常快并且难以维护。问题:有没有办法用动态数量的参数构建查询?
  2. 此代码不包含支持游标的机制。问: Spring Data 中是否有支持基于游标查询的工具?

如果回答了第一个问题,则可以轻松阅读第二个问题。

先感谢您!

4

2 回答 2

3

tl;博士

这一切都在参考文档中。

细节

Spring Data 模块非常广泛地支持Querydsl来构建参考文档中记录的动态查询。特别是对于 Spring Data JPA,在 JPA Criteria API 之上还支持规范。对于简单的排列,通过示例查询也可能是一种选择。

至于第二个问题,Spring Data 存储库支持对结果进行流式处理。也就是说,假设您出于性能原因想要这样做,那么 JPA 一开始可能不是最合适的,因为由于其实体生命周期模型,它仍会保留已处理的项目。如果它只是逐页或逐片访问结果的子集,那也是受支持的。

为了更有效地在大型数据集上进行流式传输,建议通过jOOQ(可与任何支持关系数据库的 Spring Data 模块一起使用)、Spring Data JDBC或什至 Spring Data R2DBC(如果可以选择反应式编程)来使用纯 SQL。

于 2020-08-14T07:35:03.757 回答
0

您可以使用spring-dynamic-jpa库来编写查询模板

查询模板将在执行之前根据您调用方法时的参数构建到不同的查询字符串中。

于 2020-09-21T06:02:27.970 回答