使用 withCriteria 时限制数据范围
Posted
技术标签:
【中文标题】使用 withCriteria 时限制数据范围【英文标题】:Restrict the scope of data when using withCriteria 【发布时间】:2013-10-05 15:05:25 【问题描述】:我目前有以下 3 个域类:
用户.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
]
我使用以下代码收集了一所大学的所有课程:
def courses = Course.withCriteria
universities
eq('id', Long.parseLong(params.universityId))
render courses as JSON
有一个这样的示例响应:
[
"class":"classifieds.Course",
"id":1,
"title":"Computer Science",
"universities":
["class":"University",
"id":1],
"users":
["class":"User"
,"id":1]
]
我的问题是我想限制响应的范围不包括当前返回的 users
或 universities
,我只需要在 JSON 中返回 courses
的列表。如何限制这个?
【问题讨论】:
University.get( params.long( 'universityId' ) ).courses.title as JSON
?
谢谢你 - 关闭.. 是否有可能用id
找回course
以便响应将是"id":1,"title":"Computer Science"
等的集合?
University.get( params.long( 'universityId' ) ).courses.collect [ id: it.id, title: it.title ] as JSON
? ;-)
不过可能有更有效的方法来获得相同的结果
谢谢 - 它工作。感谢您的帮助
【参考方案1】:
在引导程序中为 Course
注册所需的 JSON 对象编组器,如下所示:
//Bootstrap
def init = servletContext ->
JSON.registerObjectMarshaller(Course)
def returnObj = [:]
returnObj.id = it.id
returnObj.title = it.title
returnObj
上述寄存器仅在转换并呈现为 JSON 时返回 Course
的字段。请注意,这将永久编组 Course 以仅返回其字段而不是其关联。如果暂时需要,那么您可以很好地遵循 Tim 的方法。
如果你想让它对所有字段都通用,那么:
JSON.registerObjectMarshaller(Course)course ->
def fields = grailsApplication.domainClasses
.findit.name == 'Course'
.properties
.findAll!it.association
.name - 'version' //Remove version if req.
return fields.collectEntries[it, course."$it"]
假设grailsApplication
被注入到Bootstrap.groovy
补充一点,如果不是为了修改 JSON 的构建方式而是为了协调标准结果,那么使用projections
来获得所需的property
:
def courses = Course.withCriteria
universities
eq('id', Long.parseLong(params.universityId))
projections
property('id')
property('title')
更新:
为了以映射实体的形式检索结果,我将遵循 HQL 作为 shown here 或使用 createCriteria
并将结果转换为如下映射(未经测试):
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')
我不确定属性名称是否会创建别名。如果您遇到任何问题,您可以迅速回退到 HQL 查询。
【讨论】:
我喜欢在尝试时使用projections
的想法,但是根据您上面的内容,响应格式似乎与正常的 JSON 响应不同。它类似于([1:Computer Science],[2:Physics])
而不是"id":1,"title":"Computer Science","id":2,"title":"Physics"
尝试使用 HQL 或 createCriteria
。看我的更新。 @andymccullough以上是关于使用 withCriteria 时限制数据范围的主要内容,如果未能解决你的问题,请参考以下文章