Grails 3 - return 在 HQL 查询的查询结果中列出
Grails 3 - return list in query result from HQL query
我有一个域对象:
class Business {
String name
List subUnits
static hasMany = [
subUnits : SubUnit,
]
}
我想使用 HQL 获取名称和子单元,但出现错误
Exception: org.springframework.orm.hibernate4.HibernateQueryException: not an entity
使用时:
List businesses = Business.executeQuery("select business.name, business.subUnits from Business as business")
有没有一种方法可以使用 HQL 将结果查询结果中的子单元作为列表返回?当我使用左连接时,查询结果是一个重复名称的扁平列表。实际查询更复杂 - 这是一个简化版本,所以我不能只使用 Business.list().
我认为我应该将其添加为答案,因为我已经做了一段时间的此类事情并且可以与他人分享很多知识:
根据上面 Yariash 的建议:
这是向前遍历域对象,而不是将信息作为平面列表(地图)抓取。当拥有一个完整的对象然后要求它循环遍历和 return 许多关系与将所有对象都放在一个包含的列表中时会涉及费用
@anonymous1 左连接听起来正确 - 您可以查看添加到查询末尾的 'group by name'。或者,当您获得所有结果时,您可以使用 businesses.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 的每个内部元素作为您在该列表中 returning 的整个地图的一部分。
然后当你得到结果时
def groupedBusinesses=businesses.groupBy{it.name} 其中名称是主要 class 中具有 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 查询.
我有一个域对象:
class Business {
String name
List subUnits
static hasMany = [
subUnits : SubUnit,
]
}
我想使用 HQL 获取名称和子单元,但出现错误
Exception: org.springframework.orm.hibernate4.HibernateQueryException: not an entity
使用时:
List businesses = Business.executeQuery("select business.name, business.subUnits from Business as business")
有没有一种方法可以使用 HQL 将结果查询结果中的子单元作为列表返回?当我使用左连接时,查询结果是一个重复名称的扁平列表。实际查询更复杂 - 这是一个简化版本,所以我不能只使用 Business.list().
我认为我应该将其添加为答案,因为我已经做了一段时间的此类事情并且可以与他人分享很多知识:
根据上面 Yariash 的建议:
这是向前遍历域对象,而不是将信息作为平面列表(地图)抓取。当拥有一个完整的对象然后要求它循环遍历和 return 许多关系与将所有对象都放在一个包含的列表中时会涉及费用
@anonymous1 左连接听起来正确 - 您可以查看添加到查询末尾的 'group by name'。或者,当您获得所有结果时,您可以使用 businesses.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 的每个内部元素作为您在该列表中 returning 的整个地图的一部分。
然后当你得到结果时
def groupedBusinesses=businesses.groupBy{it.name} 其中名称是主要 class 中具有 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 查询.