【问题标题】:Add orderBy sorting into search Specification添加 orderBy 排序到搜索规范
【发布时间】:2021-03-13 16:06:13
【问题描述】:

我想通过按参数添加顺序来扩展本规范。

搜索选项 DTO:

public class ProductSearchParams {
    private String title;
    private String type;
    private LocalDateTime publishedAt;
    private String sort;
    private List<String> sortBy;
}

public Page<ProductFullDTO> findProducts(ProductSearchParams params, Pageable pageable) {
        Specification<Product> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (params.getTitle() != null) {
                predicates.add(cb.equal(root.get("title"), params.getTitle()));
            }
            if (params.getType() != null) {
                predicates.add(cb.equal(root.get("type"), params.getType()));
            }
            if (params.getPublishedAt() != null) {
                predicates.add(cb.greaterThan(root.get("publishedAt"), params.getPublishedAt()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return productService.findAll(spec, pageable).map(productMapper::toFullDTO);
    }

我试过了:

public Page<ProductFullDTO> findProducts(ProductSearchParams params, Pageable pageable) {
        Specification<Product> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (params.getTitle() != null) {
                predicates.add(cb.equal(root.get("title"), params.getTitle()));
            }
            if (params.getType() != null) {
                predicates.add(cb.equal(root.get("type"), params.getType()));
            }
            if (params.getPublishedAt() != null) {
                predicates.add(cb.greaterThan(root.get("publishedAt"), params.getPublishedAt()));
            }
            if (params.getPublishedAt() != null) {
                predicates.add(cb.greaterThan(root.get("publishedAt"), params.getPublishedAt()));
            }
            query.orderBy(builder.desc((root.join(Prodotto_.listaQuoteIng))
                    .get(QuotaIngrediente_.perc_ing)));

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return productService.findAll(spec, pageable).map(productMapper::toFullDTO);
    }

我找不到如何实现这一点的解决方案。你能在我错的地方给我建议吗?

【问题讨论】:

  • 你为什么需要那个?您已经有包含排序的分页。所以也许你错过了什么?
  • 我只是想把这个选项添加到上面的代码中。

标签: spring spring-data-jpa spring-data specifications


【解决方案1】:

在调用findAll方法之前重新创建pageable对象:

// sort = "desc" sortBy = ["listaQuoteIng.perc_ing"]
List<Sort.Order> orders = params.getSortBy().stream().map(s -> new Sort.Order("asc".equals(params.getSort()) ? ASC : DESC, s)).collect(Collectors.toList());
pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(orders));

【讨论】:

    【解决方案2】:

    您是在问如何使用sortBy 列表来指定排序顺序?以下应该有效:

    query.orderBy(sortyBy.stream()
        .map(root::get)
        .map(cb::desc)
        .toList());
    

    您还可以通过sort 查询参数(例如sort=name,asc&amp;sort=type,desc&amp;sort=listaQuoteIng.perc_ing,desc)将排序顺序传递给Pageable,并轻松地将其调整为Criteria API,请参阅this answer

    【讨论】:

    • 是的,但是你能告诉我如何将你的代码添加到我想要扩展的代码中吗?
    • 不确定我是否遵循,用上面的代码替换 query.orderBy(...) 行应该可以解决问题
    猜你喜欢
    • 1970-01-01
    • 2021-08-08
    • 2020-02-16
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多