Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用标准API与AND运算符左连接_Sql_Jpa_Predicate_Criteria Api - Fatal编程技术网

Sql 使用标准API与AND运算符左连接

Sql 使用标准API与AND运算符左连接,sql,jpa,predicate,criteria-api,Sql,Jpa,Predicate,Criteria Api,我正在尝试使用JPA和CriteriaAPI构建动态查询,但不使用元模型 关于表格: Foo: ID 1 2 3 4 我想检索没有匹配条的编号为44的所有Foo实体。(预期为Foo 1、3、4) SQL应该如下所示: select distinct * from Foo foo0_ left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44 where bar0__.id is null; CriteriaBuilder

我正在尝试使用JPA和CriteriaAPI构建动态查询,但不使用元模型

关于表格:

Foo:
ID
1
2
3
4

我想检索没有匹配条的编号为44的所有Foo实体。(预期为Foo 1、3、4)

SQL应该如下所示:

select distinct *
from Foo foo0_
left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44
where bar0__.id is null;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);

List<Predicate> allPredicates = new ArrayList<Predicate>();
List<Predicate> orPredicates = new ArrayList<Predicate>();
List<Predicate> andPredicates = new ArrayList<Predicate>();
andPredicates.add(cb.equal(fooRoot.join("bars", JoinType.LEFT).get("number"), 44));
andPredicates.add(cb.isNull(fooRoot.join("bars", JoinType.LEFT).get("ID")));
orPredicates.add(cb.and(andPredicates.toArray(new Predicate[andPredicates.size()])));
allPredicates.add(cb.or(orPredicates.toArray(newPredicate[orPredicates.size()])));

cq.where(allPredicates.toArray(new Predicate[allPredicates.size()]));
TypedQuery<Foo> query = em.createQuery(cq);
query.getResultList();
我的代码如下所示:

select distinct *
from Foo foo0_
left join Bar bar0_ on foo0_.ID=bar0_.FooID and bar0_.Number=44
where bar0__.id is null;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);

List<Predicate> allPredicates = new ArrayList<Predicate>();
List<Predicate> orPredicates = new ArrayList<Predicate>();
List<Predicate> andPredicates = new ArrayList<Predicate>();
andPredicates.add(cb.equal(fooRoot.join("bars", JoinType.LEFT).get("number"), 44));
andPredicates.add(cb.isNull(fooRoot.join("bars", JoinType.LEFT).get("ID")));
orPredicates.add(cb.and(andPredicates.toArray(new Predicate[andPredicates.size()])));
allPredicates.add(cb.or(orPredicates.toArray(newPredicate[orPredicates.size()])));

cq.where(allPredicates.toArray(new Predicate[allPredicates.size()]));
TypedQuery<Foo> query = em.createQuery(cq);
query.getResultList();
并且不返回Foo


有什么想法吗?谢谢大家!

您没有指定这是针对哪个JPA实现的,很明显,每个JPA实现的SQL可能不同

除此之外,你的加入是错误的。每个
join
调用都将执行一个join,如果编写的内容正确,则只需要一个join。您还可以在连接上使用JPA2.1“ON”条件(而不是将其放在WHERE中)

CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Foo.class);
根fooot=cq.from(Foo.class);
cq.select(foooot).distinct(true);
Join barJoin=foooot.Join(“bar”,JoinType.LEFT);
谓词onCond=cb.equal(barJoin.get(“number”),44);
barJoin.on(onCond);

然后执行与您的问题相同的操作,除了使用
barJoin
;不知道这些和/或条件要做什么-您建议的SQL没有这些功能。

我使用Hibernate JPA 2.0,所以很遗憾,barJoin.on(onCond)不起作用。and、or和all谓词用于在不同的表和不同的参数上构建动态查询;qb是QueryBuilder吗?我需要一个吗?在JPA依赖项中找不到它。是的,您满足了JPA 2.1“ON”条件,而我“改为JPA 2.1”,因为我想用正确的方式来做,但我无法让它工作。什么是qb?是的,“qb”应该是“cb”(现在更新了),Join很明显有一个“on”方法,使用谓词或表达式。
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> fooRoot = cq.from(Foo.class);
cq.select(fooRoot).distinct(true);

Join barJoin = fooRoot.join("bars", JoinType.LEFT);
Predicate onCond = cb.equal(barJoin.get("number"), 44);
barJoin.on(onCond);