JPA 2.0,Criteria API,Subqueries,In in Subquery

时间:2014-01-28 15:15:19

标签: jpa subquery criteria

我曾多次尝试用子查询和IN表达式编写查询语句。但我从来没有成功过。

在JPA中构建查询后,我总是得到不正确的结果。我的SQL请求如下:

SELECT distinct 
  ss.*
FROM
  table1 ss  
where 
  ss.active=1 
and 
  ss.id not in (select ia.organization_id from table2 ia where ia.is_allow = 'Y')

我的代码使用下面的Criteria API:

CriteriaQuery<Table1> cq = qb.createQuery(Table1.class);
Root<Table1> table = cq.from(Table1.class);
cq.select(table);
List<Predicate> predicateList = new ArrayList<Predicate>();

Subquery<Table1> subquery = cq.subquery(Table1.class);
Root<Table2> subroot = subquery.from(Table2.class);
subquery.select(subroot.get(Table2_.table1));
subquery.where(qb.equal(subroot.get(Table2_.isAllow.getName()), Boolean.TRUE));

predicateList.add(qb.not(qb.in(table.get(Table1_.id.getName())).value(subquery)));
if (!predicateList.isEmpty()) {
            Predicate[] array = new Predicate[predicateList.size()];
            cq.where(qb.and(predicateList.toArray(array)));
} 
cq.distinct(true);
TypedQuery<Table1> qry = entityManager.createQuery(cq);
return qry.getResultList();

在此之后我得到关注sql请求:

SELECT DISTINCT t0.*

FROM TABLE1 t0
WHERE (t0.ACTIVE = 1 AND NOT (t0.ID IN (SELECT 1 FROM TABLE2 t2, TABLE1 t1 WHERE ((t2.IS_ALLOW = 'Y')
AND (t1.ID = t2.ORGANIZATION_ID)))))

为什么在这段代码中“SELECT 1 FROM TABLE2 t2,TABLE1 t1”等等......我在这个t1.id中等待。

你能帮帮我吗?

1 个答案:

答案 0 :(得分:0)

如果Subquery只返回整数

select ia.organization_id from table2 ia where ia.is_allow = 'Y'

试试这个。

Subquery<Integer> subquery = cq.subquery(Integer.class);
Root<Table2> subroot = subquery.from(Table2.class);
subquery.select(subroot.get("organization_id"));
subquery.where(qb.equal(subroot.get("is_allow"), Boolean.TRUE));

上面的子查询应该返回将放在IN语句中的整数。

然后你的逻辑可以适用。

CriteriaQuery<Table1> cq = qb.createQuery(Table1.class);
Root<Table1> table = cq.from(Table1.class);
cq.select(table);
cq.distinct(true)
   .where(qb.not(qb.in(root.get("get")).value(subquery))
   .and(cb<Integer>equals(root.get("active"),1))

不确定这是否有效。 TypedQuery qry = entityManager.createQuery(cq); 如果cq“Criteria Query”是Table1.class的类型,那么TypedQuery将是 改为

TypedQuery<Table1> qry = entityManager.createQuery(cq);