【问题标题】:Criteria in relation between entities - Grails实体之间关系的标准 - Grails
【发布时间】:2016-05-16 23:17:27
【问题描述】:

我有一个包含以下实体的应用:

主题:

class Topic {

   UUID id
   String description
   String name
   boolean visibility = true

   // Relation
   static hasMany = [tests:Test]
   ...
}

测试:

class Test {

    UUID id
    boolean active = true
    String description
    ...

    static hasMany = [evaluationsTest: Evaluation]
    static belongsTo = [topic: Topic, catalog: Catalog]
}

当我向用户显示所有可见主题时,我请求查询:

def visibleTopics = Topic.findAllByVisibility(true, [sort:"name", order:"asc"])

此查询返回我,例如:[['English'], ['Spanish']]。然后,我可以向用户展示每个主题的完整信息。

但我还想向用户指出每个可见主题中的活动测试数。

例如:

English topic has 2 active test.
Spanish topic has a total of 2 test. One is active and the other is not.
German topic has not any active test.

然后我需要一个查询,其结果是:def activeTotalEachTopic = [[2],[1],[0]],我可以将activeTotalEachTopic 变量传递给视图 (.gsp)。

解决方案:

从我可以获得所有可见主题的第一个查询中,我得到了活动测试的数量。

def visibleTopics = Topic.findAllByVisibility(true, [sort:"name", order:"asc"])

def numberActiveTest = []

activeTopics.each { topic ->
    def result = Test.findAllByTopicAndActive(topic, true).size()
    numberActiveTest.push(result)
}

我将两个变量都传递给视图。

render view: 'home', model: [activeTopics: activeTopics, numberActiveTest: numberActiveTest]

【问题讨论】:

    标签: grails criteria grails-2.0 hibernate-criteria grails-domain-class


    【解决方案1】:

    您缺少的是分组,以便您获得每组的计数,而不是总计数。

    您还需要将连接类型从默认的内连接更改为外连接,以便没有活动测试的主题返回 0。但是,这样做的副作用是它会更改关联属性的引用方式,因为到由连接创建的别名。像这样的:

    import static org.hibernate.sql.JoinType.*
    
    def activeTotalEachTopic =  Topic.createCriteria().list() {
        createAlias('tests', 't', LEFT_OUTER_JOIN)
    
        eq 'visibility', true
    
        or {
            eq 't.active', true
            isNull 't.id'
        }
    
        projections {
           groupProperty 'name'
           count()
        }        
        order ("name", "asc")
    }
    

    现在,要解决的另一个问题是,由于分组:[['English', 2],['Spanish', 1],['German', 0]],输出会是这样的。所以你可以做的是收集每个子列表中的第二项:

    activeTotalEachTopic*.getAt(1)
    
    // Which is the equivalent of...
    
    activeTotalEachTopic.collect { it[1] }
    

    【讨论】:

    • 谢谢。它不能完美地工作。它仅显示具有活动测试的主题,因此:[['English', 2],['Spanish', 1]]。 德语主题不在列表中。
    • 好的,我修复了 null 问题。问题是当没有关联的测试时,t.active 变为 null,导致条件失败。所以空检查将解决这个问题。
    • 问题仍然存在。不显示没有主动测试的主题。如果省略了 projections 部分,它只会出现两个主题;第三个没有出现(德语)。
    • 随便玩吧!注意:您需要投影来进行计数或任何类型或分组。了解 SQL 非常很方便。 docs.grails.org/2.2.x/api/grails/orm/…
    • 是的,我知道预测是必要的。这只是一个检查查询是否正常工作的示例。在这种情况下,它不能很好地工作,因为没有获得没有主动测试的主题。这为什么呢?
    猜你喜欢
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2021-04-07
    相关资源
    最近更新 更多