首页 文章

子选择在休眠标准中

提问于
浏览
12

我有一个带有列名的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的标准?

谢谢你的期待 .

3 回答

  • 2

    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 .

  • 3

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

    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();
    
  • 1

    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"
        )
    })
    

相关问题