何时在 grails 中使用 executeUpdate

bar*_*mac 4 grails hibernate hql grails-orm

我正在查看当前项目中的一些 grails gorm 代码,我想知道以下 HQL 方法有哪些优缺点:

UploadUpsell.executeUpdate("update UploadUpsell set processedStatus=:newStatus, processedDate=:processedDate where processedDate is null and period=:period",
                            [newStatus: EXPIRED_UPSELL_STATUS, processedDate: new Date(), period: flow.period])
Run Code Online (Sandbox Code Playgroud)

我本来会采用更惯用的方法

UploadUpsell.findAllByPeriodAndProcessedDate(flow.period, null).each { UploadUpsell uploadUpsell ->
                    uploadUpsell.with {
                        processedStatus = EXPIRED_UPSELL_STATUS
                        processedDate = new Date()
                        save()
                    }
                }
Run Code Online (Sandbox Code Playgroud)

我相信我的方法会更具可测试性并且更具可读性,但我想知道我的想法是否只是教条主义

据我所知,grails 模拟框架不支持 HQL 语句。

Bur*_*ith 5

您的方法更具可读性,但性能要差得多。您将所有实例读入内存,包括您不会更改的数据,进行更改,并将所有内容(包括未更改的值)推回数据库。如果您的域类和它们的值很小,这没什么大不了的(特别是如果记录数量不是太大),但通常这种方法是一个可伸缩性问题。

通过使用 executeUpdate 直接运行查询,您可以让数据库做它擅长的事情——它可以找到需要更新的记录并完成工作,而无需数据库和 Web 服务器之间的所有不必要的流量。

单元测试不支持 HQL 是对的,但您不应该对域类进行单元测试。如果您不针对数据库测试持久性,那么您正在测试的只是模拟框架。

  • 在事务中包装查询不会改变查询的数量。 (2认同)