使用withCriteria时限制数据范围 [英] Restrict the scope of data when using 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。如何限制它?
为课程$ c $注册所需的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 universities
that 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屋!