【问题标题】:Criteria - DetachedCriteria in GrailsCriteria - Grails 中的 DetachedCriteria
【发布时间】:2016-04-24 22:05:55
【问题描述】:

第一个问题:

我的应用中有以下域类:

class Test {

 ...
 String name
 static hasMany = [evaluationsTest: Evaluation]
 ...

}

class Evaluation {
 ...
 String testName
 Float testScore
 ...
}

我需要获取特定测试的分数范围(例如:分数在 7-8 之间的评估)之间的评估次数。

有一个标准我可以正确获得

def criteria = Test.createCriteria()
def example = criteria.list {
   eq 'name', params.test
   evaluationsTest {
      ge("testScore", 7 as Float)
      lt("testScore", 8 as Float)
   }
   projections {
      count()
   }
}

但我想知道异步搜索,因此我想使用 DetachedCriteria 但它不起作用。

DetachedCriteria detached = Test.where {
   name == params.test
   evaluationsTest {
      ge("testScore", 7 as Float)
      lt("testScore", 8 as Float)
   }
   .projections {
      count()
   }
} as DetachedCriteria

def result = detached.async.list()

已编辑:使用 withCriteria() 方法解决。

第二个问题:

此外,我还有一个疑问。我需要并行化这段代码。我该怎么做每个片段?我曾经task,但有时会工作,有时会出现错误:Array Index Out of Bounds Exception

// Rows
def rows = []
def addRow = { name, value ->
    rows << [c: [[v: name], [v: value]]]
}
// Add departments
departments.each { department ->
    addRow(department.name, department.users.size())
}
def UDData = [cols: cols, rows: rows]

通过这段代码(任务),我得到:数组索引越界

List queriesToExecute = []

// Add departments - Asynchronous/Multi-thread
departments.each { department ->
    def departmentTask = tasks {
        rows << [c: [[v: department.name], [v:department.users.size()]]]
     }
     queriesToExecute << departmentTask
 }
 waitAll(queriesToExecute)

【问题讨论】:

  • “不起作用”是什么意思?请添加相关错误/stacktraces/...

标签: hibernate grails grails-orm criteria grails-2.0


【解决方案1】:

您的查询可能失败的一个原因是因为您正在创建 where 查询而不是 criteria 查询,而 where 查询确实如此不能很好地支持预测。他们工作......但只是有时。而且您必须在查询之外定义它们,如下所示:

DetachedCriteria detached = Test.where {
   name == params.test
   evaluationsTest {
      ge("testScore", 7 as Float)
      lt("testScore", 8 as Float)
   }   
}.projections {
      count()
} as DetachedCriteria

但是,您实际上并不需要 DetachedCriteria 来执行异步查询。您可以使用 criteria 查询来做到这一点:

def promise = Test.async.withCriteria() {
   eq 'name', params.test
   evaluationsTest {
      ge("testScore", 7 as Float)
      lt("testScore", 8 as Float)
   }
   projections {
      count()
   }
}

def result = promise.get()

同时收集部门

这是一个使用 GPars 来同时收集部门数据的示例,没有副作用:

import static groovyx.gpars.GParsPool.withPool

def rows

withPool {
    rows = departments.collectParallel { department ->
        [c: [[v: department.name], [v:department.users.size()]]]
    }
}

def UDData = [cols: cols, rows: rows]

这是使用 fork-join。所以Closure是并发执行的,然后结果被join在一起。

【讨论】:

  • 谢谢。我不知道 withCriteria() 我可以使用异步选项。现在我还有一个疑问(请看第二个问题)。
  • 我认为问题在于您试图从多个线程追加到列表。这是一个禁忌,因为ArrayList,这是您使用def x = [] 得到的不是线程安全的。我对 GPars 生疏了,但我知道它能够满足您的需求。也许有并行集合。
  • 我使用了这个例子:dzone.com/articles/example-using-grails-promises,但正如我所说,有时效果很好,有时会出现错误:Array Index Out of Bounds Exception
  • 那个代码和你的区别在于你的有副作用;它同时添加到列表中。这样做可能会导致您遇到的问题。它只在某些时候起作用。
  • 我添加了一个示例来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 2011-05-14
相关资源
最近更新 更多