Hibernate Criteria使用IN子句和子选择查询多个列

时间:2013-11-04 20:47:51

标签: java sql hibernate hibernate-criteria

我的问题与this question非常相似。

我从table1中选择了table2中field3和field4的所有匹配唯一组合的所有数据。

这是我剥离的SQL:

select *
from table1 as t1
where (t1.field1, t1.field2) in (select distinct field3, field4
                                 from table2 as t2
                                 where t2.id=12345);

我需要将我的SQL翻译成Hibernate Criteria。我让我的实体对象正确映射到表并将响应转换为正确的结果实体,但我无法正确翻译我的where子句。

我有什么

Criteria criteria = getSession().createCriteria(Table1.class);

DetachedCriteria subquery = DetachedCriteria.forClass(Table2.class);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("field3"), "field3");
projectionList.add(Projections.property("field4"), "field4");
subquery.setProjection(Projections.distinct(projectionList));
subquery.add(Restrictions.eq("id", 12345));

我希望我的where子句类似于:

criteria.add(Subqueries.in("field1, field2", subquery));

但是Hibernate不允许这样做。

我试过推出where子句以获得两个子查询,并根据结果检查field1和field2,但看起来子查询总是必须返回多个列。我使用group by做了这个,但是Hibernate会自动将组中的列添加到投影列表中,我找不到删除它们的方法。

以下是使用group by的相同查询:

select *
from table1 as t1
where t1.field1 in (select field3
                    from table2 as t2
                    where t2.id=12345
                    group by field3, field4)
  and t1.field2 in (select field4
                    from table2 as t2
                    where t2.id=12345
                    group by field3, field4);

是否可以使用Hibernate Criteria执行where子句?

如果无法使用Hibernate Criteria,是否可以使用HQL执行where子句?

修改

@ Larry.Z使用HQL回答我的问题。

我能用Hibernate Criteria解决我的问题,但我不得不将查询修改为:

select *
from table1 as t1
where exists (select 1
              table2 as t2
              where t2.id=12345
                and t2.field3=t1.field1
                and t2.field4=t1.field2);

转换为Hibernate标准:

Criteria criteria = getSession().createCriteria(Table1.class, "t1");

DetachedCriteria subquery = DetachedCriteria.forClass(Table2.class, "t2");
subquery.add(Restrictions.eq("t2.id", 12345));
subquery.add(Restrictions.eqProperty("t2.field3", "t1.field1"));
subquery.add(Restrictions.eqProperty("t2.field4", "t1.field2"));
subquery.setProjection(Projections.property("t2.id")); // select the ID rather than 1

我仍然很好奇是否可以使用原始SQL编写Hibernate Criteria。

2 个答案:

答案 0 :(得分:5)

尝试像这样编写HQL查询

String hql = "from Table1 t1 where (t1.field1, t1.field2) in (
    select distinct t2.field3, t2.field4
    from Table2 t2
    where t2.id=12345)";
sessionFactory.getCurrentSession().createQuery(hql).list()

答案 1 :(得分:4)

Subqueries.propertiesIn就是您所需要的:

criteria.add(Subqueries.propertiesIn(
                new String[] { "field1", "field2" },
                detachedCriteria));