Grails 3.3.0 /Gorm:如何使用连接进行查询



我相信这很容易,但在文档或谷歌中找不到任何示例。

假设我们有客户和帐户域对象,因此:

Class Customer {
String name
}
Class Account {
Customer customer
BigDecimal balance
Currency currency
}

如果我不使用grails,并且没有ORM,我会在原始SQL中做这样的事情:

Select c.name, a.balance
from customer c, account a 
where name like xxx 
and a.customer_id = c.id

甚至:

Select c.*, a.balance, a.currency_id
from customer c, account a 
where name like xxx 
and a.customer_id = c.id

甚至:

Select c.*, a.balance, cur.iso
from customer c, account a, currency cur 
where name like xxx 
and a.customer_id = c.id
and cur.id = a.currency_id

但是,在圣杯中,我正在寻找一种方法来返回一组已加载帐户的客户。 这样我就可以将 Customer 对象传递回视图,而不是字符串列表。

这必须作为单个查询完成,而不是作为一个查询来获取所有客户,然后为每个客户查询以获取他们的余额(可能有数百万个客户(

我知道 grails 会延迟加载,如果我想,我可以在每次查询玩家时强制 grails 加载帐户,但这会影响我想查找客户但不需要余额的时间。

我也知道我可以在 grails 中硬编码 SQL/HQL,并将结果作为字符串返回以供 gsp 页面呈现,但这不太像 grails。

此外,我不想在播放器中添加指向许多帐户的链接,因为这可能会对性能产生严重影响,并且不是通用解决方案(我有大约 400 个域对象,其中许多对象需要一个联接查询解决方案(。

请注意,此示例假设每个玩家都有一个帐户。如果这不是真的,如果我通过 SQL 执行此操作,我将使用外部连接。不知道 GORM 中的等价物是什么。

有什么建议吗?

更新答案,因为我没有正确阅读。

首先,您提到在视图中执行gormHQL查询。也许有一天你会感谢我,但你真的应该尝试保持演示作为演示。当你试图做发现或复杂的决策时,是时候退后一步,思考概念是否需要重新思考,或者如果不可能,如何将这个逻辑实现到一个要么工作,要么依赖服务来完成工作的taglib

到目前为止,您需要的最简单答案是修改 Customer 类并执行自定义 Set/Let 来抓取属于其他对象的对象:

Class Customer {
String name
Set<Account> getAccounts() { 
return (Account?.findAll{customer==this} as Set<Account>)
/// Or write hql you can also add things like take to limit it
//return Account?.findAllByCustomer(this)?.take(5)
}
Account getAccount() { 
return Account?.find{customer==this} 
}
}

然后,当您遍历所有用户时

<g:each in ="${instance.customers}" var="customer">
${u.name} vs ${customer?.account?.balance} ${customer?.accounts?.balance}
</g:each>

只有当你击中每个用户时,才会调用 getter

或者尝试将其全部编写为一个查询,该查询获取所有内容,该查询可能在查询中或查询外部进行分组,但是它起作用并传入偏移量和最大值,然后将其列出,以便然后使用分页来控制如此多的记录,HQL 查询的基础知识将是这样的(因为您希望所有用户可能有也可能没有余额,而客户没有与客户有关系(

String query= """Select new map(c.name as name, a.balance as balance) 
from Customer c, Account a
where name like :name
and a.customer.id = c.id
"""

Map mp=[:]
name='%'+params.name+'%'
def result=Account.executeQuery(query,mp,[readOnly:true])

相关内容

  • 没有找到相关文章

最新更新