Hibernate Grails一对多抽象类

Hibernate Grails一对多抽象类,hibernate,grails,groovy,gorm,single-table-inheritance,Hibernate,Grails,Groovy,Gorm,Single Table Inheritance,在我们的应用程序中,我们有一个玩家可以有游戏和练习计划,因此我们设计了抽象类计划和两个派生类GamePlan和PracticePlan。在数据库中,派生类保存到具有“class”属性的单个表中 当我们在一个特定的玩家身上使用getPlans()时,我们会得到所有的计划,但我们想知道如何只获得游戏或练习计划。类似于player.getPracticePlans()或player.PracticePlans(player\u id)的内容。下面是我们的课程 class Player {

在我们的应用程序中,我们有一个玩家可以有游戏和练习计划,因此我们设计了抽象类计划和两个派生类GamePlan和PracticePlan。在数据库中,派生类保存到具有“class”属性的单个表中

当我们在一个特定的玩家身上使用getPlans()时,我们会得到所有的计划,但我们想知道如何只获得游戏或练习计划。类似于player.getPracticePlans()或player.PracticePlans(player\u id)的内容。下面是我们的课程

class Player  {

    String name
    static hasMany = [ plans : Plan] 
}

abstract class Plan {
}

class PracticePlan extends Plan{
}

class GamePlan extends Plan{
}
注意:我们尝试使用以下内容:

def query = Player.where {
    plans {  class == "GamePlan" }
}   

但是该类是一个保留关键字,它不会编译。

我相信您可以这样做来加载一个人的所有计划,然后过滤掉不需要的计划:

def gamePlansForPlayer = Player.get( id ).plans.findAll { plan ->
  plan.instanceOf( GamePlan )
}

但未测试:-(

我相信您可以这样做来加载一个人的所有计划,然后过滤掉不需要的计划:

def gamePlansForPlayer = Player.get( id ).plans.findAll { plan ->
  plan.instanceOf( GamePlan )
}

但是没有测试它:-(

您应该能够使用
getClass()
获取类。请参阅以下答案:

您还可以使用,它会将列置于引号中,这样就不会遇到保留字问题:

def plans = Player.withCriteria {
    plans {
        eq('class', "com.name.space.GamePlan")
    }
}
(注意,我用名称空间指定类名,因为它是如何存储在我的experience.YMMV中的。)

如果这样做有效,并且希望使其更通用,则可以将其设置为,并将该类作为参数提供:

def namedQueries = {
    plansByClass = { clazz ->
        plans {
            eq('class', clazz)
        }
    }
}
然后将其称为静态方法:

def plans = Player.plansByClass('GamePlan')

请注意,虽然我在应用程序中使用了条件,但这些特定示例未经测试。

您应该能够使用
getClass()
获取类。请参见以下答案:

您还可以使用,它会将列置于引号中,这样就不会遇到保留字问题:

def plans = Player.withCriteria {
    plans {
        eq('class', "com.name.space.GamePlan")
    }
}
(注意,我用名称空间指定类名,因为它是如何存储在我的experience.YMMV中的。)

如果这样做有效,并且希望使其更通用,则可以将其设置为,并将该类作为参数提供:

def namedQueries = {
    plansByClass = { clazz ->
        plans {
            eq('class', clazz)
        }
    }
}
然后将其称为静态方法:

def plans = Player.plansByClass('GamePlan')

请注意,虽然我在应用程序中使用了标准,但这些特定示例没有经过测试。

您是否计划将类
归到
Player?不,一个计划可以在多个用户之间共享。就我个人而言,我只会执行static hasMany=[gamePlans:GamePlan,practicePlans:PracticePlan].这不会简化事情吗?也许我们会采用你建议的方法,这样可能会有较少的问题,但我们希望它们结合在一起的原因是因为两者的逻辑是相同的,所以我想我们不会有重复的代码。你是否计划将类
归属于
播放器?不,一个计划可以在多个用户之间共享。个人最后,我只需要做静态hasMany=[gamePlans:GamePlan,practicePlans:PracticePlan].这不会简化事情吗?也许我们会采用您建议的方法,这样可能会有较少的问题,但我们希望将它们结合在一起的原因是因为两者的逻辑相同,所以我想我们不会有重复的代码。这是行得通的,谢谢!您能回答我吗,hibernate是否从公共数据库加载所有计划实例用于GamePlan和PracticePlan的表,并在应用程序级别对其进行过滤,或者在查询中进行过滤?如果它加载所有内容,最好说玩家分别有PracticePlan和GamePlan?这将把
玩家的所有计划加载到内存中,然后将该列表过滤到
GamePlan
实例中。我会关于这个问题,请稍等,因为其他人可能知道如何编写HQL或在数据库级别编写HQL的标准,以避免这种开销…它可以工作,谢谢!请回答我,hibernate是从GamePlan和PracticePlan的公共表加载所有计划实例,并在应用程序级别对其进行筛选,还是在查询中进行筛选?如果它会加载所有内容,如果说玩家分别拥有PracticePlans和GamePlans会更好吗?这会将
玩家的所有计划加载到内存中,然后将该列表向下过滤到
GamePlan
实例中。我会就这个问题稍等片刻,因为其他人可能知道编写HQL的方法或编写HQL的标准在数据库级别,避免这种开销…Ieu Cristo我刚刚意识到这是从2012年开始的>\U Ieu Cristo我刚刚意识到这是从2012年开始的>_