英文:
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) -> {
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) -> {
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 ='alfacentauri')
Thanks!
答案1
得分: 2
以下是翻译好的内容:
你应该在谓词内部这样使用 Subquery
return (root, query, builder) -> {
Subquery<Long> subquery = query.subquery(Long.class); // 如果 b.id_A 的类型是 Long
Root<B> subRoot = subquery.from(B.class);
final Predicate codeFieldPredicate =
builder.equal(subRoot.get("code_field"), "alfacentauri");
subquery.select(subRoot.get("id_A")).where(codeFieldPredicate);
return builder.in(root.get("id")).value(subquery);
}
另一种方法是使用 exists
谓词
return (root, query, builder) -> {
Subquery<Long> subquery = query.subquery(Long.class);
Root<B> subRoot = subquery.from(B.class);
final Predicate mainQueryPredicate =
builder.equal(root.get("id"), subRoot.get("id_A"));
final Predicate codeFieldPredicate =
builder.equal(subRoot.get("code_field"), "alfacentauri");
subquery.select(subRoot.get("id_A")).where(mainQueryPredicate , codeFieldPredicate);
return builder.exists(subquery);
}
它生成了一个稍微不同的查询,但结果将如预期。
英文:
You should use Subquery
inside predicate this way
return (root, query, builder) -> {
Subquery<Long> subquery = query.subquery(Long.class); // if b.id_A has Long type
Root<B> subRoot = subquery.from(B.class);
final Predicate codeFieldPredicate =
builder.equal(subRoot.get("code_field"), "alfacentauri");
subquery.select(subRoot.get("id_A")).where(codeFieldPredicate);
return builder.in(root.get("id")).value(subquery);
}
Another approach is to use exists
predicate
return (root, query, builder) -> {
Subquery<Long> subquery = query.subquery(Long.class);
Root<B> subRoot = subquery.from(B.class);
final Predicate mainQueryPredicate =
builder.equal(root.get("id"), subRoot.get("id_A"));
final Predicate codeFieldPredicate =
builder.equal(subRoot.get("code_field"), "alfacentauri");
subquery.select(subRoot.get("id_A")).where(mainQueryPredicate , codeFieldPredicate);
return builder.exists(subquery);
}
It generates a bit different query, but result will be as expected
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论