使用withCriteria时限制数据范围 [英] Restrict the scope of data when using withCriteria

查看:131
本文介绍了使用withCriteria时限制数据范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有以下3个网域类别:

User.groovy

  class User {
...

static hasMany = [
...
]

static belongsTo = [
课程:课程,
大学:大学
]

}

Course.groovy

  class Course {

字符串标题

static hasMany = [
大学:大学,
用户:用户
]

static belongsTo =大学

}

University.groovy

  class University {

字符串名称

static hasMany = [
课程:课程,
用户:User
]
}

我使用以下代码收集大学的所有课程:

  def courses = Course.withCriteria {
大学{
eq('id',Long.parseLong params.universityId))
}
}
将课程呈现为JSON



<例如:

  [{
class:classifieds.Course,
id:1,
title:计算机科学,
大学:
[{class:University,
id :1}],
users:
[{class:User
,id:1}]
}]

我的问题是我想限制响应的范围,使其不包含 users 大学目前正在退回,我只是列出课程 JSON。如何限制它?

解决方案

课程

  //引导程序
def init = {servletContext - >
JSON.registerObjectMarshaller(Course){
def returnObj = [:]
returnObj.id = it.id
returnObj.title = it.title

returnObj


上述寄存器只返回字段当转换并呈现​​为JSON时,课程。请注意,这将永久编组课程只返回其字段而不是其关联。如果需要暂时的,那么你可以很好地遵循Tim的方法。



如果你想为所有字段设置通用的,那么:

  JSON.registerObjectMarshaller(Course){course  - > 
def fields = grailsApplication.domainClasses
.find {it.name =='Course'}
.properties
.findAll {!it.association}
.name - '版本'//如果请求删除版本。

return fields.collectEntries {[it,course。$ it]}
}

提供的 grailsApplication 被注入到 Bootstrap.groovy



要添加,如果不打算修改构建JSON的方式,但要调整条件结果,请使用 projection 来获取所需的 property

  def courses = Course.withCriteria {
Universities {
eq('id',Long.parseLong(params.universityId))
}
预测{
property('id')
property('title')
}
}

更新: >
为了将结果作为映射实体进行检索,我将遵循HQL,如此处显示或使用 createCriteria 并将结果转换为如下所示的映射(未测试):

  import org。 hibernate.tr ansform.Transformer 

def criteria = Course.createCriteria()
criteria.resultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
def courses = criteria.list {
大学{
eq('id',Long.parseLong(params.universityId))
}
预测{
property('id')
property('title')




$ b我不确定别名是否由属性名创建。我遇到任何问题,都可以迅速回退到HQL查询。


I currently have the following 3 domain classes :

User.groovy

class User {
    ...

    static hasMany = [
        ...
        ]

    static belongsTo = [        
        course : Course,
        university : University     
        ]

}

Course.groovy

class Course {

    String title

    static hasMany = [
        universities : University, 
        users : User
        ]

    static belongsTo = University       

}

University.groovy

class University {

    String name

    static hasMany = [
        courses : Course,
        users : User
        ]           
}

I gather all of the courses for a university with the following code :

def courses = Course.withCriteria {      
          universities {
            eq('id', Long.parseLong(params.universityId))
          }
        }
        render courses as JSON  

With an example response like so :

[{
            "class":"classifieds.Course",
            "id":1,
            "title":"Computer Science",
            "universities":
                [{"class":"University",
                    "id":1}],
            "users":
                [{"class":"User"
                    ,"id":1}]
        }]

My issue is that I want to restrict the scope of the response to not include the users or universitiesthat are currently being returned, I only what a list of courses to be returned in the JSON. How to I restrict this?

解决方案

Register your desired JSON Object marshaller for Course in bootstrap as below:

//Bootstrap
def init = { servletContext ->
    JSON.registerObjectMarshaller(Course){
        def returnObj = [:]
        returnObj.id = it.id
        returnObj.title = it.title

        returnObj
    }
}

The above registers to only return the fields of Course when converted and rendered to JSON. Note this is going to permanently marshal Course to only return its fields and not its associations. If needed temporarily then you can very well follow Tim's approach.

In case you want to make it generic for the all the fields, then:

JSON.registerObjectMarshaller(Course){course ->
    def fields = grailsApplication.domainClasses
                                  .find{it.name == 'Course'}
                                  .properties
                                  .findAll{!it.association}
                                  .name - 'version' //Remove version if req.

    return fields.collectEntries{[it, course."$it"]}
}

provided grailsApplication is injected to Bootstrap.groovy

To add, if the intention is not to modify the way JSON is built but to reconcile the criteria result then use projections to get the required property:

def courses = Course.withCriteria {      
   universities {
     eq('id', Long.parseLong(params.universityId))
   }
   projections{
      property('id')
      property('title')
   }
}

UPDATE:
In order to retrieve results as mapped entities then I would follow HQL as shown here or use createCriteria and transform the result to map as below (untested):

import org.hibernate.transform.Transformers

def criteria = Course.createCriteria()
criteria.resultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
def courses = criteria.list {      
   universities {
     eq('id', Long.parseLong(params.universityId))
   }
   projections{
      property('id')
      property('title')
   }
}

I am not sure aliases will be created by the property names. I you face any issue, you can swiftly fallback to HQL query.

这篇关于使用withCriteria时限制数据范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆