[英]Grails: Updating a single object in a domain, “.save” Vs “.executeUpdate”
我想知道从数据库中的一行更新域类中的单个值的最有效方法是什么。 可以说域类有20多个字段
def itemId = 1
def item = Item.get(itemId)
itemId.itemUsage += 1
Item.executeUpdate("update Item set itemUsage=(:itemUsage) where id =(:itemId)", [usageCount: itemId.itemUsage, itemId: itemId.id])
vs
def item = Item.get(itemId)
itemId.itemUsage += 1
itemId.save(flush:true)
如果未更新字段的大小和数量很大(并且这是主观的),则executeUpdate更有效。 这也是我经常删除实例的方式,运行'从Foo中删除id = 123',因为我完全加载实例只是为了调用它上面的delete()似乎很浪费。
如果您的域类中有大字符串并使用get()和save()方法,那么当您需要更改的所有字段都是一个字段时,您将所有这些数据从数据库序列化到Web服务器两次。
如果您正在使用它,则需要考虑对二级缓存的影响(如果您编辑很多实例,则可能不应该这样做)。 使用executeUpdate,它将刷新之前使用get()加载的所有实例,但如果使用get + save进行更新,则只刷新该实例。 如果你是群集的话,这会变得更糟,因为在执行executeUpdate之后,你要清除所有各种群集节点缓存,而不是刷新所有节点上的一个实例。
最好的办法是对两种方法进行基准测试。 如果您没有超载数据库,那么您可能会过早地进行优化,并且在解决其他问题时使用标准方法可能最好保持简单。
如果你使用get
/ save
,你将获得hibernate缓存的最大优势。 executeUpdate
可能会强制更多选择和更新。
executeUpdate
与hibernate缓存交互的方式在这里有所不同。 hibernate缓存在executeUpdate
失效。 在executeUpdate之后,该项的下一次访问必须转到数据库(可能更多,我认为hibernate可能会使缓存中的所有项无效)。
最好的办法是在Config.groovy中启用'org.hibernate'的调试日志记录并检查SQL调用。
我认为他们是平等的。 两者都发出2个sql调用。
更高效的只是一次更新
Item.executeUpdate("update Item set itemUsage=itemUsage+1 where id =(:itemId)", [ itemId: itemId.id])
您可以在Item类中使用dynamicUpdate mapping属性:
http://grails.org/doc/latest/ref/Database%20Mapping/dynamicUpdate.html
启用此选项后,使用Gorm更新单个字段的第二种方法将与第一种方法一样高效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.