【问题标题】:Performing createCriteria() on Parent where the Child and its property is evaluated在评估 Child 及其属性的 Parent 上执行 createCriteria()
【发布时间】:2016-05-31 12:08:19
【问题描述】:

我在 Grails 中使用 Hibernate 并正确设置 Parent 域类和 Child 域类,完全配置,具有静态 hasManybelongsTo 属性。对于这个场景,我们只使用类名ParentChild,不过,它也可以应用于其他场景,实用性。

为了测试这个映射,我还执行了许多成功的 CRUD。虽然过了一段时间,出现了提前查询。我目前正在执行一些“高级”查询,我在下面总结了这些查询。使用给定的Domain 映射:

class Parent {
    Long id
    static hasMany = [ children: Child ]
}

class Child {
    Long id
    static belongsTo = [ parent: Parent ]
}

如何选择以下条件:

  1. 选择所有没有孩子的父母
  2. 选择所有有孩子的父母
  3. 选择所有有男孩的父母(因此,当通过as JSON groovy 类型转换转换为 JSON 时,应该只包括男孩)

我不知道如何开始编码 1 和 2,也许与 child.size() 有关——我真的不知道。虽然我在 3 中的想法是:

ArrayList<Parent> PARENTS_WITH_SON = Parent.createCriteria().list {
    children {
        eq("gender", "male")
    }
}

但问题是,当转换为 JSON 时,它包含非男性条目。有人可以帮我查询吗?使用createCriteria() 会很好,但也可以在HQL 中使用。

【问题讨论】:

    标签: json hibernate grails groovy


    【解决方案1】:

    1 和 2 真的很简单:

    1.选择所有没有孩子的父母

    Parent.createCriteria().list {
        sizeEq("children", 0)
    }
    

    2。选择所有有孩子的父母

    Parent.createCriteria().list {
        sizeGt("children", 0)
    }
    

    3。选择所有有男孩的父母(因此,当通过 as JSON groovy 类型转换转换为 JSON 时,应该只包括男孩)

    Parent.createCriteria().listDistinct {
        children {
            eq("gender", "male")
        }
    }
    

    使用上述查询,您将获得有男孩的父母的集合。但是当您进行直接 JSON 转换时,GORM 将获取所有父级的子级。因此,您可以编写自定义 JSON 转换器,或者我们可以修改查询以仅返回 Map 中所需的数据。

    /*
      create a new Grails Criteria that internally will use
      Hibernate's org.hibernate.Criteria.
    */
    List<Map<String, Object>> resultList = Parent.createCriteria().list {
        /*
         Set a strategy for handling the query results.
         This determines the "shape" of the query result.
    
         See org.hibernate.Criteria.setResultTransformer(...)
    
         CriteriaSpecification.ALIAS_TO_ENTITY_MAP transformer will transform the results into a Map<String, Object>
        */
        resultTransformer(org.hibernate.criterion.CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
    
        /*
         Join an association using the specified join-type, 
         assigning an alias to the joined association.
    
         org.hibernate.Criteria.createAlias(...)
        */
        createAlias("children", "child", JoinType.INNER_JOIN);
    
        projections {
            property("id", "parentId")
            property("child.id", "childId")
            property("child.gender", "gender")
        }
    
        eq("child.gender", "MALE")
    }
    

    这将为您提供一个 Map 列表,其中包含 parentId、childId 和性别作为其键。 Json 将是:

    [
      {
        "childId": 1,
        "gender": "MALE",
        "parentId": 2
      },
      {
        "childId": 3,
        "gender": "MALE",
        "parentId": 2
      },
      {
        "childId": 4,
        "gender": "MALE",
        "parentId": 3
      },
      {
        "childId": 5,
        "gender": "MALE",
        "parentId": 3
      }
    ]
    

    【讨论】:

    • 如果可以的话,能详细说明resultTransformer()createAlias()createCriteria()的功能吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多