Grails在域类上有效批量删除,级联删除到子类

时间:2013-03-07 16:18:43

标签: mysql grails gorm

人们使用哪些技术有效地对大量类进行级联删除?

假设我有以下域类:

class Submission {
   static hasMany = [members: Member]
}

class Member {
   static belongsTo = [submission: Submission]
   static hasMany = [events: Event, hashCodes: HashCode]
}

class Event {
   static belongsTo = [member: Member]
}

class HashCode {
   static belongsTo = [member: Member]
}

现在,提交的提交内容的成员数量可能非常大,比如10万以上,但这并不限制。事件和HashCodes每个成员会说15个。

我需要删除给定提交的部分或全部成员(让我们暂时假设所有成员),但保留提交记录不变。所以我目前这样做如下:

Set<Member> membersToDelete = Member.findAllBySubmissionId( submission.id )
withSessionCleaner(membersToDelete){ member ->
   submission.payroll.removeFromMembers( member )
   member.delete( failOnError: true )
}

其中一些通用基本服务将会话清理程序提供为:

SessionFactory sessionFactory
def propertyInstanceMap = org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP
private static final int DEFAULT_SESSION_CLEANER_CHECKPOINT = 100
def withSessionCleaner(def items, Closure c)
{
    items.eachWithIndex { obj, index ->
       c(obj)
       if (++index % DEFAULT_SESSION_CLEANER_CHECKPOINT == 0) {
           def session = sessionFactory.currentSession
           session.flush()
           session.clear()
           propertyInstanceMap.get().clear()
        }
    }
}

需要会话清理方法,否则Grails会保留会话缓存中的所有对象,最终导致内存不足问题和/或处理开始需要很长时间才能收集。

我对这种方法的主要关注点是:

  1. 什么是Grails读取或从db加载到内存中的Member / Event / HashCode类?我听说过延迟加载,但不知道如何在这3个类上检查或配置它。
  2. 单独处理每个成员对于级联删除工作似乎是必要的,但对于我想要实现的目标而言似乎可能很昂贵。
  3. 我可以运行一些SQL查询来实现我的目标:

    1. 从event_id中的事件中删除(从成员中选择id,其中submission_id =?)
    2. 从HashCode中删除其中的member_id(从成员中选择id,其中submission_id =?)
    3. 从提交文件中删除submission_id =?
    4. 但现在我使用的是原始SQL,并没有真正使用Grails类或关系。 Grails / GORM命令是否等同于这些SQL语句?

      有什么建议吗?

1 个答案:

答案 0 :(得分:0)

最快的方法是在子对象上使用ON DELETE CASCADE创建FOREIGN KEYS(希望您的数据库允许您这样做)。之后,您可以安全地按ID删除成员,数据库将完成剩下的工作。