【问题标题】:Hibernate Criteria Query for multiple columns with IN clause and a subselect带有 IN 子句和子选择的多列的休眠条件查询
【发布时间】:2013-11-15 14:37:00
【问题描述】:

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

我正在为 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 中的列添加到投影列表中,我找不到删除它们的方法。

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

翻译成休眠标准:

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等,是你要找的吗?docs.jboss.org/hibernate/core/3.3/api/org/hibernate/criterion/…
  • 不,我不这么认为。我正在尝试使用 Hibernate Criteria 中的元组编写“IN”子句。看起来休眠不会让我从子选择中返回一个元组(例如 ['field3', 'field4'] );它也不会让我使用“IN”比较元组。或者,我尝试使用两个子查询来展开我的查询,但 Hibernate 喜欢将额外的列添加到投影中。看看我的第一个子查询 - 按 field3 和 field4 分组将在子查询的结果中返回 field3 和 field4,即使我只指定返回 field3。

标签: java sql hibernate hibernate-criteria


【解决方案1】:

尝试像这样编写 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()

【讨论】:

  • 谢谢拉里.Z。出于某种原因,我之前无法让(子选择)中的“(元组)”工作。如果可能的话,我宁愿坚持使用 Hibernate Criteria,但这是一个很好的选择!
【解决方案2】:

Subqueries.propertiesIn 是你需要的:

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

【讨论】:

    猜你喜欢
    • 2012-09-06
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 2017-02-13
    • 2013-10-08
    相关资源
    最近更新 更多