【发布时间】:2023-03-10 02:57:01
【问题描述】:
我有一个域类 Widget,我需要从中删除所有实例——清除它。之后,我将加载新数据。您建议采用什么机制来做到这一点?
附:请注意,这不是在引导时,而是在“运行时”。
【问题讨论】:
标签: grails grails-orm
我有一个域类 Widget,我需要从中删除所有实例——清除它。之后,我将加载新数据。您建议采用什么机制来做到这一点?
附:请注意,这不是在引导时,而是在“运行时”。
【问题讨论】:
标签: grails grails-orm
最简单的方法是直接使用HQL:
DomainClass.executeUpdate('delete from DomainClass')
【讨论】:
DomainClass.findAll().each { it.delete() }
如果您想避免任何 GORM 陷阱,例如需要立即删除对象并检查以确保它确实被删除,请添加一些参数。
DomainClass.findAll().each { it.delete(flush:true, failOnError:true) }
【讨论】:
相当老的帖子,但仍然是真实的。
如果您的表非常大(数百万个条目),使用 findall()*.delete() 进行迭代可能不是最佳选择,因为您可能会遇到事务超时(例如 MySQL innodb_lock_wait_timeout 设置),除了说明的潜在内存问题作者:GreenGiant。
所以至少对于 MySQL Innodb,使用 TRUNCATE TABLE 更快:
sessionFactory.currentSession
.createSQLQuery("truncate table ${sessionFactory.getClassMetadata(MyDomainClass).tableName}")
.executeUpdate()
这仅在您的表未被其他对象作为外键引用时才有用。
【讨论】:
据我所知,我同意@ataylor 如果您的域对象中没有关联(在任何实际应用程序中极不可能),则以下代码是最快的:
DomainClass.executeUpdate('delete from DomainClass')
但是,如果您与其他域有关联,那么最安全的删除方法(也比上面提到的要慢一点)如下:
def domainObjects = DomainClass.findAll()
domainObjects.each {
it.delete(flush:it==domainObjects.last, failOnError:true)
}
【讨论】:
如果你有一个对象列表并且想要删除所有元素,你可以使用*操作符。
'*' will split the list and pass its elements as separate arguments.
示例。
List<Book> books = Book.findAllByTitle('grails')
books*.delete()
【讨论】: