grails GORM 派生属性

grails GORM derived properties

我的 grails 域对象中有一个字段,我想将其作为其他表的派生字段。我的域名如下所示

class VotingTally{

   int votesSource1
   int votesSource2
   int totalVotes

}

static mapping = {
    totalVotes formula: (votesSource1.numOfVotes+ votesSource2.numOfVotes)
}

我得到的错误是

No such property: votesSource1 for class: org.grails.datastore.mapping.config.groovy.MappingConfigurationBuilder

首先,formula 应该是一个带有 SQL 表达式的字符串(你有 Groovy 表达式)。喜欢:

static mapping = {
    totalVotes formula: 'numOfVotes1 + numOfVotes2'
}

但在您的情况下,您想要计算连接表的值,这是不可能的。您不能从这里添加 JOIN

看来你只有一种方法 - 从代码加载它:

static transients = ['totalVotes']

int getTotalVotes() {
    VotesSource.get(votesSource1).numOfVotes + VotesSource.get(votesSource2).numOfVotes 
}

正如 Andrew von Dollen 所提到的,您仍然可以通过使用子选择来使用公式,但这并不总是最佳选择。另外,您的域需要有一种方法来关联两个投票源(通常是 one-to-many 或 many-to-many 关系)。相当于:

static mapping = { totalVotes formula: '((select count(*) from vote_source_1 vs1 where vs1.source_id = id) + (select count(*) from vote_source_2 vs2 where vs2.source_id = id))' }

请注意,以上内容可能不适合您。它取决于您的特定数据库引擎和您的域模型,通过一些共享 ID 链接投票源以执行加入。

优点:

  • 您可以像任何其他 属性
  • 一样对 属性 值进行排序和查询
  • 避免创建非规范化数据库
  • 将处理成本放入数据库(也可能是一个con...)

缺点:

  • 如果使用 non-standard SQL.
  • 可以引入数据库引擎类型依赖
  • 不会在新的或脏的实例上给出准确的值,因为 属性 在实例被保存(并且可能被刷新)之前无效或更新