我有一个实体,学生,在Student.groovy中定义为:
@EqualsAndHashCode(includes = ['id'])
class Student {
Long id
String name
String type
University university
static mapping = {
university column : 'UNIVERSITY_ID'
}
}
和大学实体,在University.groovy中定义为:
class University {
Long id
String name
static mapping = {
id column : 'id', generator : 'assigned'
}
}
我一直试图从调用
切换Student.list(sort: ..., order: ...)
致电:
Student.findAll("from Student s where type = :type ", [type : 'T'], [ sort : 'name' ])
这无法通过名称字段正确排序。使用list
的先前版本工作正常。
我也试过调用类似
的东西Student.findAll(sort : 'name') { type == "T" }
这样工作得很好,但在尝试按university.name
排序时Student.findAll(sort : 'university.name') { type == 'T" }
它引发了关于找不到university.name字段的错误。
任何人都知道如何正确地做到这一点?
谢谢。
答案 0 :(得分:3)
使用executeQuery
代替findAll
- 它们的功能相同,但我发现executeQuery
由于某种原因是HQL的更直接调用者,{ {1}}在某些情况下失败或返回意外结果。
这样第一个查询就是
findAll
按大学名称排序
Student.executeQuery(
'select s from Student s where s.type = :type order by s.name',
[type : 'T'])
我喜欢HQL并倾向于使用它,但它会将您与Hibernate和关系数据库结合在一起 - 如果您想切换到NoSQL数据库,这些查询将会失败。标准查询,"其中"查询和查找程序都在内部使用条件查询,并由GORM实现转换为本机查询API调用。
等效标准查询将是
Student.executeQuery(
'select s from Student s where s.type = :type order by s.university.name',
[type : 'T'])
和
Student.withCriteria {
eq 'type', 'T'
order 'name', 'asc'
}
一些不相关的说明:
您不应在Student.withCriteria {
eq 'type', 'T'
university {
order 'name', 'desc'
}
}
或id
计算中使用equals
;如果你有一个持久的hashCode
和一个具有相同名称,类型和大学的新非持久化实例,它们应该被认为是相同的,但由于非持久化实例的id将为null,它们&# 39;被认为是不同的。
您不需要指定Student
属性 - Grails会在编译期间通过AST转换将其和id
字段添加到字节码中。
无需将version
属性的列名映射到' UNIVERSITY_ID' - 无论如何都是这样。
您可以省略university
映射中的冗余column
设置。
这里删除了学生课程:
id
和大学:
@EqualsAndHashCode(includes = ['name', 'type', 'university'])
class Student {
String name
String type
University university
}