【问题标题】:Grails: Updating a single object in a domain, ".save" Vs ".executeUpdate"Grails:更新域中的单个对象,“.save”与“.executeUpdate”
【发布时间】:2010-10-01 20:15:39
【问题描述】:

我想知道从数据库中的一行更新域类中的单个值的最有效方法是什么。假设域类有 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)

【问题讨论】:

    标签: grails hql save


    【解决方案1】:

    如果未更新字段的大小和数量很大(这是主观的),则执行更新会更有效。这也是我经常删除实例的方式,运行 'delete from Foo where id=123' 因为完全加载实例只是为了调用 delete() 对我来说似乎很浪费。

    如果您的域类中有较大的字符串并使用 get() 和 save() 方法,那么当您只需要更改一个字段时,您会不必要地将所有数据从数据库序列化到 Web 服务器两次。

    如果您正在使用二级缓存,则需要考虑对它的影响(如果您经常编辑实例,您可能不应该这样做)。使用 executeUpdate 它将刷新以前使用 get() 加载的所有实例,但是如果您使用 get + save 进行更新,则仅刷新那个实例。如果您是集群的,情况会变得更糟,因为在 executeUpdate 之后,您将清除所有各种集群节点缓存而不是刷新所有节点上的一个实例。

    最好的办法是对这两种方法进行基准测试。如果您没有使数据库过载,那么您可能会过早地进行优化,并且在解决其他问题时使用标准方法可能最好让事情保持简单。

    【讨论】:

      【解决方案2】:

      如果您使用get/save,您将获得休眠缓存的最大优势。 executeUpdate 可能会强制进行更多选择和更新。

      executeUpdate 与休眠缓存交互的方式在这里有所不同。休眠缓存在executeUpdate 上失效。在 executeUpdate 之后对该 Item 的下一次访问将 必须 进入数据库(可能更多,我认为 hibernate 可能会使缓存中的所有 Item 无效)。

      最好的办法是在 Config.groovy 中为“org.hibernate”打开调试日志并检查 SQL 调用。

      【讨论】:

        【解决方案3】:

        我认为他们是平等的。两者都发出 2 个 sql 调用。

        更高效的只是一次更新

        Item.executeUpdate("update Item set itemUsage=itemUsage+1 where id =(:itemId)", [ itemId: itemId.id])
        

        【讨论】:

          【解决方案4】:

          您可以在 Item 类中使用 dynamicUpdate 映射属性:

          http://grails.org/doc/latest/ref/Database%20Mapping/dynamicUpdate.html

          启用此选项后,您使用 Gorm 更新单个字段的第二种方法将与第一种方法一样有效。

          【讨论】:

          • dynamicUpdate 彻底改变了我们的应用程序!感谢您分享这个超级提示。还有吗?
          猜你喜欢
          • 2010-12-29
          • 1970-01-01
          • 2020-09-24
          • 1970-01-01
          • 2016-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多