我编写了一个代码来从我的数据库中获取一些实体,代码非常难看(代码重复等),对于大块实体来说并不是很快。 代码获取所有实体,然后对其进行排序(在内存中),然后获取一系列项目(用于对结果进行分页)。
它是:
List<T> retrieveData() {
def filterPastEvents = (params.filterPastEvents) ?: 0
def entities = retrieveUnsortedData(filterPastEvents).sort {
entity1, entity2 ->
entity2.criterion1 <=> entity1.criterion1 ?:
entity1.criterion2 <=> entity2.criterion2 ?:
entity1.criterion3 <=> entity2.criterion3
}
if (params.offset != null && params.max != null) {
return entities.subList(params.offset, Math.min(params.to+1,entities.size()))
} else {
return entities
}
}
private List<Entity> retrieveUnsortedData(filterPastEvents) {
List<Entity> entityList
if (params.param1 && params.params2) {
entityList = Entity.findAll({
param1 == params.param1
params2 == params.params2
endTimeUTC >= filterPastEvents
})
}
if (params.param1 && !params.params2) {
entityList = Entity.findAll({
param1 == params.param1
endTimeUTC >= filterPastEvents
})
}
if (params.params2 && !params.param1) {
entityList = Entity.findAll({
params2 == params.params2
endTimeUTC >= filterPastEvents
})
}
if (entityList == null) {
entityList = Entity.findAll({
endTimeUTC >= filterPastEvents
})
}
return entityList
}
我认为使用标准并且没有重复的代码会更有效率,尽管此代码有效。
这就是我试图简化代码的原因:
List<T> retrieveData() {
def filterPastEvents = (params.filterPastEvents) ?: 0
Closure closureOrder = {
endTimeUTC >= filterPastEvents
order('criteria1', 'desc')
order('criteria2', 'asc')
order('criteria3', 'desc')
}
Closure param1Closure = {}
if (params.param1) {
param1Closure = {
param1 == params.param1
}
}
Closure param2Closure = {}
if (params.param2) {
param2Closure = {
param2 == params.param2
}
}
return Entity.findAll(max: params.max, offset: params.offset).list {
param1Closure
param2Closure
closureOrder
}
}
我的问题是,在这一点上:
关闭不运行&#39;,param1上的条件和param2不正确。
和这段代码
Closure param1Closure = {}
if (params.param1) {
param1Closure = {
param1 == params.param1
}
}
仍然与param2重复。
如何根据条件构成闭包(即:params.param1?),我尝试使用Closure c&lt;&lt; param1Closure但它似乎不起作用。
答案 0 :(得分:1)
这是一种更简单的方法:
List<T> retrieveData() {
Entity.findAll(max: params.max, offset: params.offset) {
if(params.param1) param1 == params.param1
if(params.param2) param2 == params.param2
if(params.filterPastEvents) endTimeUTC >= filterPastEvent
order 'criteria1', 'desc'
order 'criteria2', 'asc'
order 'criteria3', 'desc'
}
}
上面的示例非常简洁,但如果您真的想使用合成,则可以compose where queries。像这样:
import grails.gorm.DetachedCriteria
List<T> retrieveData() {
...
DetachedCriteria<Entity> param1Closure = (params.param1 ? { param1 == params.param1 } : { }) as DetachedCriteria<Entity>
...
def query = Entity.where(param1Closure)
query = query.where(param2Closure)
query = query.where(closureOrder)
return query.list(max: params.max, offset: params.offset)
}
重要的一点是,如果用变量作为闭包调用where(Closure)
,则闭包必须转换为DetachedCriteria
。定期关闭不起作用。