Spring 数据规范 orderBy 子查询

Posted

技术标签:

【中文标题】Spring 数据规范 orderBy 子查询【英文标题】:Spring Data Specification orderBy subquery 【发布时间】:2020-03-03 11:41:28 【问题描述】:

在我的 mysql 项目中,我得到了这个具有 3 个实体的特殊模型:Prodotto 和许多子节点 QuotaIngrediente,这反过来也是 Ingrediente 的多对一子节点。我所有的关系都是双向的。 他们都获得了一个自动生成的整数 ID,并删除了其他字段以专注于有趣的字段。

@Entity
public class Prodotto 
    private List<QuotaIngrediente> listaQuoteIng = new ArrayList<QuotaIngrediente>();

    @OneToMany(mappedBy = "prodotto", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<QuotaIngrediente> getListaQuoteIng() 
        return listaQuoteIng;
    
@Entity
public class QuotaIngrediente

    private Prodotto prodotto;

    private Ingrediente ing;

    private Double perc_ing;

    @ManyToOne
    @JoinColumn(name = "prodotto")
    public Prodotto getProdotto() 
        return prodotto;
    

    @ManyToOne
    @JoinColumn(name = "ing")
    public Ingrediente getIng() 
        return ing;
    
@Entity
public class Ingrediente 
    private Set<QuotaIngrediente> quoteIng = new HashSet<QuotaIngrediente>();

    @OneToMany(mappedBy = "ing", cascade = CascadeType.ALL, orphanRemoval = true)
    public Set<QuotaIngrediente> getQuoteIng() 
        return quoteIng;
    

我正在使用 SpringData 规范,我可以构建一个查询以根据成分标准获取 Prodotto,这样:

public static Specification<Prodotto> getProdottoByIngSpec (String ing) 

    if (ing != null) 
        return (root, query, criteriaBuilder) -> 
            query.groupBy(root.get(Prodotto_.id));

            return criteriaBuilder.like(((root.join(Prodotto_.listaQuoteIng))
                                                .join(QuotaIngrediente_.ing))
                                                .get(Ingrediente_.nome), "%"+ing+"%");
        ;

它按预期工作,但现在我想按特定成分的 QuotaIngrediente perc_ing 字段对其进行排序。 显然,我问的是如何在数据库上做,而不是在业务逻辑中。

【问题讨论】:

当 b 是集合时,按b.a 排序是什么意思?如果您将SortlistaQuoteIng.perc_ing 一起使用,会发生什么情况?抱歉,如果我遗漏了一些重要的东西,但是当所有的名字对我来说毫无意义时,很难遵循代码。 @JensSchauder 每个Prodotto(产品)都有一个项目列表(QuotaIngrediente)。每个项目都由两个字段组成:foreign key 指定属于产品的一种成分 (Ingrediente),以及一个整数,用于测量特定产品的成分含量百分比 (perc_ing)。我想根据特定成分的含量对产品列表进行排序。如果我只是通过listaQuoteIng.perc_ing 限制我的排序,它将考虑所有产品中每种成分的百分比,而不仅仅是我想要排序的那个。 @JensSchauder 我对一个无关紧要的问题失去了理智。我认为我的查询返回了符合我的约束条件的任何产品的所有成分。相反,它实际上只返回匹配的成分,然后正如您正确指出的那样,我只是按 listaQuoteIng.perc_ing 排序。我通过将此子句添加到我的规范 query.orderBy(builder.desc((root.join(Prodotto_.listaQuoteIng)).get(QuotaIngrediente_.perc_ing))); 来实现这一点,如果您有任何改进,请将其写在单独的答案中,我会将其标记为解决方案。 很高兴听到。请将答案发布为正确答案,或关闭/删除该问题,以免人们对此进行处理。 【参考方案1】:

由于我的错误假设,我正在努力解决一个错误的问题。解决方案是最简单的。只需按 orderBy CriteriaQuery 方法排序。我用来搜索的查询已经过滤了 QuotaIngrediente,只返回与我的搜索条件匹配的行。那么这是我必须添加到规范中的唯一一行:

query.orderBy(builder.desc((root.join(Prodotto_.listaQuoteIng))
                                   .get(QuotaIngrediente_.perc_ing)));

【讨论】:

以上是关于Spring 数据规范 orderBy 子查询的主要内容,如果未能解决你的问题,请参考以下文章

子查询

使用 Spring JPA 规范按子查询排序

Oracle - 子查询TOP - N

第四章 MySQL高级查询

使用子表单过滤器和 orderby 参数进行查询

子查询(嵌套子查询)