【发布时间】:2012-06-26 02:17:19
【问题描述】:
我想在我的域类中实现默认排序顺序,但立即发现它不适用于 getAll 方法。没什么大不了的,我只是用list 代替。问题是域类中的默认排序顺序不允许您指定多个排序字段 (as seen here)。
我的目标是首先按照 Bar 对象的名称对所有 Foo 对象进行排序,然后按照它们自己的名称排序。
class Foo {
String name
String Bar
}
class Bar {
String name
}
如何在域类中实现这一点,这样我就不必在每次调用 .list() 时都指定一个冗长/讨厌的比较器?
我的一个尝试:
static Comparator getComparator() {
def c = { a, b ->
def result = a.bar.name.compareTo( b.bar.name );
if ( result == 0 ) {
result = a.name.compareTo( b.name );
}
}
return c as Comparator
}
然后我可以打电话给Foo.list(Foo.getComparator())...如果我能让它工作的话。
更新:
我想我在这里真的很接近,只是在同一个排序闭包中实现两个比较时遇到了麻烦。
Foo.list().sort{ a, b ->
def result = a.bar.name <=> b.bar.name;
// Things mess up when I put this if statement in.
if( result == 0 ) {
a.name <=> b.name
}
}
迪斯科!
class Foo { // My domain class
// ...
static Comparator getComparator() {
def c =[
compare: { a, b ->
def result = a.bar.name <=> b.bar.name;
if( result == 0 ) {
result = a.name <=> b.name
}
return result
}
] as Comparator
}
// ...
}
并在我的控制器中这样实现:
Foo.list().sort( Foo.getComparator() )
PS:
上述方法有效,但 Jeff Storey 在我发现后在他的答案中发布了一些代码,他的代码有效并且比我的要好得多,所以使用它:)
【问题讨论】:
-
看起来你找到了答案,仅供参考,使用
a.bar.name <=> b.bar.name ?: a.name <=> b.name是带有后备比较键的惯用常规情况。另外,由于这些是域对象,如果可以的话,我建议您在数据库中进行排序。除非它们的集合非常小,否则在 groovy 中执行此操作可能会慢几个数量级。 -
在数据库中做意味着通过executeQuery方法的HQL对吗?
-
是的,我就是这样做的。您可能也可以为此使用条件,但我发现条件写起来比 HQL 更难写,HQL 非常接近 SQL。