JPA中的in子句使用规范 – JHipster方法

huangapple go评论65阅读模式
英文:

JPA in clause using Specification - JHipster approach

问题

我有两个实体 A 和 B。A 包含一个 Set<B>,在 QueryService 中,我需要按照 B 的字段 X 进行过滤。

我看到了 Predicate,但我不明白如何使用它。

    	StringFilter lf = new StringFilter(); lf.setEquals(value);
    	return (root, query, builder) -&gt; {
    		Predicate p = builder.in(expression);
    		return builder.and(p);
    	};

在 "expression" 中放入什么???? 以获得类似以下的结果:

SELECT * FROM A WHERE 
A.id in (select b.id_A from b where b.code_field ='alfacentauri')

谢谢!

英文:

I have 2 Entities A, B. A contains a Set<B> and I need in the QueryService to filter by a field X of B.

I see Predicate, but I do not understand how to use it.

    	StringFilter lf = new StringFilter(); lf.setEquals(value);
    	return (root, query, builder) -&gt; {
    		Predicate p = builder.in(expression);
    		return builder.and(p);
    	};

What put in "expression"???? to obtain something like:

SELECT * FROM A WHERE 
A.id in (select b.id_A from b where b.code_field =&#39;alfacentauri&#39;)

Thanks!

答案1

得分: 2

以下是翻译好的内容:

你应该在谓词内部这样使用 Subquery

return (root, query, builder) -&gt; {
    Subquery&lt;Long&gt; subquery = query.subquery(Long.class); // 如果 b.id_A 的类型是 Long
    Root&lt;B&gt; subRoot = subquery.from(B.class);
        
    final Predicate codeFieldPredicate = 
        builder.equal(subRoot.get(&quot;code_field&quot;), &quot;alfacentauri&quot;);
        
    subquery.select(subRoot.get(&quot;id_A&quot;)).where(codeFieldPredicate);

    return builder.in(root.get(&quot;id&quot;)).value(subquery);
}

另一种方法是使用 exists 谓词

return (root, query, builder) -&gt; {
    Subquery&lt;Long&gt; subquery = query.subquery(Long.class);
    Root&lt;B&gt; subRoot = subquery.from(B.class);
            
    final Predicate mainQueryPredicate = 
        builder.equal(root.get(&quot;id&quot;), subRoot.get(&quot;id_A&quot;));
    final Predicate codeFieldPredicate = 
        builder.equal(subRoot.get(&quot;code_field&quot;), &quot;alfacentauri&quot;);
            
    subquery.select(subRoot.get(&quot;id_A&quot;)).where(mainQueryPredicate , codeFieldPredicate);
    
    return builder.exists(subquery);
}

它生成了一个稍微不同的查询,但结果将如预期。

英文:

You should use Subquery inside predicate this way

return (root, query, builder) -&gt; {
    Subquery&lt;Long&gt; subquery = query.subquery(Long.class); // if b.id_A has Long type
    Root&lt;B&gt; subRoot = subquery.from(B.class);
        
    final Predicate codeFieldPredicate = 
        builder.equal(subRoot.get(&quot;code_field&quot;), &quot;alfacentauri&quot;);
        
    subquery.select(subRoot.get(&quot;id_A&quot;)).where(codeFieldPredicate);

    return builder.in(root.get(&quot;id&quot;)).value(subquery);
}

Another approach is to use exists predicate

return (root, query, builder) -&gt; {
    Subquery&lt;Long&gt; subquery = query.subquery(Long.class);
    Root&lt;B&gt; subRoot = subquery.from(B.class);
            
    final Predicate mainQueryPredicate = 
        builder.equal(root.get(&quot;id&quot;), subRoot.get(&quot;id_A&quot;));
    final Predicate codeFieldPredicate = 
        builder.equal(subRoot.get(&quot;code_field&quot;), &quot;alfacentauri&quot;);
            
    subquery.select(subRoot.get(&quot;id_A&quot;)).where(mainQueryPredicate , codeFieldPredicate);
    
    return builder.exists(subquery);
}

It generates a bit different query, but result will be as expected

huangapple
  • 本文由 发表于 2020年9月9日 20:10:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63811411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定