Grails 3 - 来自HQL查询的查询结果中的返回列表

时间:2016-07-13 23:40:49

标签: grails hql gorm grails-3.0

我有一个域对象:

class Business {
    String name
    List subUnits

    static hasMany = [
            subUnits : SubUnit,
    ]
}

我想使用HQL获取名称和subUnits,但是我收到错误

Exception: org.springframework.orm.hibernate4.HibernateQueryException: not an entity

使用时:

List businesses = Business.executeQuery("select business.name, business.subUnits from Business as business")

有没有办法可以使用HQL将结果查询结果中返回的subUnit作为List?当我使用左连接时,查询结果是一个复制名称的扁平List。实际查询更复杂 - 这是一个简化版本,所以我不能只使用Business.list()。

1 个答案:

答案 0 :(得分:1)

我认为我应该将其添加为答案,因为我一直在做这类事情以及我可以与他人分享的大量知识:

根据Yariash的建议:

这是向前走过域对象与获取信息作为平面列表(地图)。有一个整个对象然后要求它循环并返回许多关系而不是将它全部包含在一个包含的列表中会涉及费用

@ anonymous1通过左连接听起来是正确的 - 您可以按名称查看'组'添加到查询结尾。或者当你拥有所有结果时,你可以使用business.groupBy {it.name}(这是一个很酷的groovy功能)看看groupBy的输出,以了解它对

做了什么

但是如果你试图抓住整个物体并将其映射回来,那么实际上成本仍然非常高,并且可能与Yariash的建议一样昂贵且可能更糟。

List businesses = Business.executeQuery("select new map(business.name as name, su.field1 as field1, su.field2 as field2) from Business b left join b.subUnits su ")

以上是你应该尝试做的事情,离开加入然后抓取hasMany的每个内部元素作为你在该列表中返回的所有地图的一部分。

然后当你有结果时

def groupedBusinesses = businesses.groupBy {it.name}其中name是主类中具有hasMany关系的主要对象。

如果您再看一下,您会看到每个名字都有自己的列表

groupedBusinesses: [name1: [ [field1,field2,field3], [field1,field2,field3] ]

你现在可以做到

groupedBusinesses.get(name) to get entire list for that hasMany relation.

为上面的hql查询启用SQL日志记录,然后将其与

进行比较
List businesses = Business.executeQuery("select new map(b.name as name, su as subUnits) from Business b left join b.subUnits su ")

您将看到第二个查询将生成巨大的SQL查询以获取数据,因为它尝试映射每行的整个条目。

我已经测试了这个理论,如果不是从HQL中创建的多个SQL查询页面与第一个示例创建的几行查询相比,它总是倾向于整个页面充满查询。