【问题标题】:JPA Specification - Check values in multiple rowsJPA 规范 - 检查多行中的值
【发布时间】:2023-03-17 18:33:02
【问题描述】:

我的数据库中有一对多关系,加入后如下所示:

 Person id | Attribute id
--------------------------
     A     |      1
     A     |      2
     A     |      3

我想要做的是返回一个人,如果它有一个我作为参数传递的属性列表,使用规范与 JPARepository 进行过滤,但是同一个人有多行给我带来了一些麻烦,我不知道该怎么做。

作为规范的一些代码示例:

public static Specification<Person> hasAllAttributes(List<Long> attr) {

    return (root, query, cb) -> {
       Root<Attribute> rootA = query.from(Attribute.class);
        root.alias("p");
        rootA.alias("at");

        Predicate samePerson = cb.equal(root.get(Person_.ID), rootA.get(Attribute_.PERSON));

        Predicate hasAttribute = rootA.get(Attribute_.ID).in(attr);

        return cb.and(samePerson, hasAttribute);
    };
}

这使它像一个或一样工作,如果它具有一个属性,它会返回 Person,如果它包含列表中的多个属性,则返回它多次。所以这实际上不是我想要的,我猜它是不完整的,但我不知道如何添加这个限制。

【问题讨论】:

  • 分享代码将有助于提出建议。像这样:Person findTopByAttributesIn(List&lt;String&gt; attributes);,如果您只对匹配属性的一个人感兴趣,将返回一个人。
  • 你是对的,我没有发布任何代码,因为它没有错,但我认为它不完整。但它可以帮助指导和澄清我现在的观点。谢谢你告诉我!
  • 也许有更简单的方法,但我通常通过返回提供列表中的属性数量等于提供列表大小的所有人员来做到这一点。这需要一个相关的计数子查询。
  • 您能否发布一些说明如何形成该子查询的代码?谢谢!

标签: java hibernate jpa spring-data-jpa criteria-api


【解决方案1】:

解决了,我只需要了解子查询,然后使用一个将属性与列表进行匹配并计算匹配项以检查列表中的所有项是否都返回:

public static Specification<Person> hasAllAttributes(List<Long> attr) {

    return (root, query, cb) -> {

        Subquery<Long> subquery = query.subquery(Long.class);
        Root<Attribute> subRoot = subquery.from(Attribute.class);
        subquery.select(cb.count(subRoot));

        Predicate samePerson = cb.equal(root.get(Person_.ID), subRoot.get(Attribute_.PERSON));
        Predicate attributeInList = subRoot.get(Attribute_.ID).in(attr);

        subquery.where(cb.and(samePerson, attributeInList));

        return cb.equal(subquery, attr.size());
    };
}

【讨论】:

    猜你喜欢
    • 2019-12-07
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 2018-09-06
    • 2022-11-18
    • 2017-10-28
    • 1970-01-01
    相关资源
    最近更新 更多