使用Hibernate Criteria查询多个列,包含IN子句和子查询

4

我有一个问题,与这个问题非常相似。

我正在从table2中选择field3和field4的所有匹配唯一组合,以获取table1中的所有数据。

以下是我简化后的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 中的列添加到 projection 列表中,无法找到删除它们的方法。

这是使用 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 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。


限制条件包括AND、OR等,这是您要寻找的吗?https://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/criterion/Restrictions.html - kosa
不,我不这么认为。我正在尝试使用Hibernate Criteria中的元组编写“IN”子句。看起来Hibernate不允许我从子查询中返回元组(例如['field3','field4']),也不允许我使用“IN”比较元组。作为替代方案,我尝试使用两个子查询来滚动我的查询,但是Hibernate喜欢将额外的列添加到投影中。请查看我的第一个子查询-按field3和field4分组将在子查询结果中返回field3和field4,即使我只指定返回field3。 - CoffeePasta
2个回答

6

试着按照以下方式编写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
感谢Larry.Z。出于某种原因,我之前无法让“(元组)在(子查询)中”正常工作。如果可能的话,我更喜欢使用Hibernate Criteria,但这是一个很好的替代方案! - CoffeePasta

5

Subqueries.propertiesIn是你所需的:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接