grails - Grails 3.3.0/Gorm:如何通过联接进行查询

标签 grails gorm

我确信这很容易,但是在documentation或google中找不到任何示例。

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

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对象传递回 View ,而不是字符串列表。

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

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

我也知道我可以在grails中对SQL / HQL进行硬编码,并且只将结果作为字符串返回给gsp页面以进行渲染,但这并不是很像grails。

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

注意,此示例假设每个玩家都有一个帐户。如果这不是真的,那么如果我通过SQL进行操作,我将使用外部联接。完全不知道GORM中的等效功能。

有什么建议么?

最佳答案

由于我没有正确阅读内容,因此正在更新答案。

首先,您提到在 View 中进行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>

仅当您击中每个用户时, setter/getter 才会被调用

或者尝试将其全部编写为一个查询,以使所有内容都可以在查询中或查询外部进行分组,但是它可以正常工作并传递offset和max值,然后将其列出,因此您可以使用分页来控制很多记录,这是基础知识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])

关于grails - Grails 3.3.0/Gorm:如何通过联接进行查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45031980/

相关文章:

grails - 在Grails中多次重定向响应

grails - grails removeFrom在集成测试中不起作用

grails - Grails/GORM属于返回引用命名

grails - Grails不会保存域的字段

grails - Grails标准投影-通过两个属性的不同投影

grails - 尝试从 Grails 应用程序中的长数字中删除逗号

java - 如何强制下载 Excel 文件?

grails - 在Grails中创建动态变量名称

grails - Grails访问关系表

grails - Grails GORM MongoDB插件中是否有类似可搜索的search()方法的类似方法?