【问题标题】:Sub-Select In hibernate criteria休眠条件中的子选择
【发布时间】:2017-04-17 12:30:04
【问题描述】:

我有一个带有列名的 sql 表 A

name, id1, id2, val1

还有一个带有列名的表 B

id1, id2, key1, key2

这是我的 sql 查询

SELECT
  v1.id1,
  v1.id2
FROM (
       SELECT
         A.id1,
         A.id2,
         min(val1) AS x
       FROM A
         JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
       GROUP BY A.id1, A.id2
     ) AS v1
WHERE v1.x > 10

使用 DetachedCriteria 我能够形成子查询

DetachedCriteria subCriteria = DetachedCriteria.forClass(A_model.class);
subCriteria.createAlias("b", "b_model");
subCriteria.setProjection(Projections.projectionList()
                            .add(Projections.groupProperty("id1"))
.add(Projections.groupProperty("id2"))
.add(Projections.min("val1"),"x");

但我在创建外部查询时遇到了困难。

任何建议我如何为上述 SQL 创建条件?

感谢期待。

【问题讨论】:

  • 标准查询适用于实体,而不是表。我们不知道实体长什么样。
  • @JBNizet 我已经为我想要的表和 sql 提供了列。除此之外,您还需要更多信息吗?您能否建议通过标准进行子选择的通用解决方案?(随意假设任何相应的实体结构)

标签: java postgresql hibernate criteria hibernate-criteria


【解决方案1】:

Hibernate 暂时不支持from 子句中的子选择。但是,您可以使用HAVING 子句以更简单、更有效的形式重写您的查询:

SELECT A.id1, A.id2,
FROM A JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
GROUP BY A.id1, A.id2
HAVING min(val1) > 10

上述查询可以轻松移植到 HQL 或 Criteria。

【讨论】:

    【解决方案2】:

    考虑为您需要的数据创建一个视图:

    create view A_B_BY_ID1_AND_ID2 as
    select A.id1,
           A.id2,
           min( val1 ) as x
    from A
    join B on A.id1 = B.id1 and A.id2 = B.id2
    group by A.id1,
             A.id2
    

    然后创建一个 DTO 来表示这个数据:

    @Entity(table="A_B_BY_ID1_AND_ID2")
    @Data //are you on board with lombok?
    public class ABById1AndId2 {
        @Column
        private int x;
        @Column
        private int id1;
        @Column
        private int id2;
    }
    

    然后像其他任何东西一样访问它:

    session.createCriteria(ABById1AndId2.class).add(Restrictions.gt("x", 10)).list();
    

    【讨论】:

      【解决方案3】:

      HQL 和 Criteria 对象都不支持从 Select 中选择。这里的解决方案是命名查询。

      @NamedNativeQueries({
          @NamedNativeQuery(
          name = "findV1",
          query = "SELECT
                    v1.id1,
                    v1.id2
                  FROM (
                         SELECT
                           A.id1,
                           A.id2,
                           min(val1) AS x
                         FROM A
                           JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
                         GROUP BY A.id1, A.id2
                       ) AS v1
                  WHERE v1.x > 10"
          )
      }) 
      

      【讨论】:

        猜你喜欢
        • 2012-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多