Including the max and offset criteria inside GORM criteriaBuilder returns an error

我怕爱的太早我们不能终老 提交于 2019-12-12 12:27:13

问题


Can I make this code shorter?

if(count == null && from = null) {
    creditAdviceList = CreditAdvice.findAll {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from == null) {
    creditAdviceList = CreditAdvice.findAll(max: count) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count == null && from != null) {
    creditAdviceList = CreditAdvice.findAll(offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from != null) {
    creditAdviceList = CreditAdvice.findAll(max: count, offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}

You see, its a series if statement for each possible scenario. Imagine if one would to use also order and cache in the parameter- there will be basically 16 unique if statements!

I've tried this [more] shorter code:

creditAdviceList = CreditAdvice.findAll {
    ilike('id', "%$idFilter%")
    .....
    ilike('statusCode', statusCodeFilter)

    if(count != null) {
        maxResults(count)
    }
    if(from != null) {
        firstResult(from)
    }
}

But it gives me an error:

...No signature of method: grails.gorm.DetachedCriteria.maxResults() is applicable for argument types: (java.lang.Integer)...

I tried to convert offset to int, Integer, String, etc. I also omit the if statement inside the criteria, but the same error message occur.


回答1:


findAll with a closure passed is using a DetachedCriteria internally, which is not the same as the result you would get from createCriteria mentioned in the docs. If groovy would find "something close" enough, it would tell you in the error message. The easiest way to deal with your max/from demands would be with simply with a map (which is the first argument passed). E.g.:

def qcfg = [:]
if (count) {
    qcfg.count = count
}
if (from) {
    qcfg.offset = from
}
creditAdviceList = CreditAdvice.findAll(qcfg) { ... }

mix, match, extract, shorten as you see fit




回答2:


As far as I see, the only difference is the pagination options. If my eyes are not tricking me, yes, you can:

Map paginationArgs = [max: count, offset: from].findAll { 
   it.value != null 
}
List<CreditAdvice> creditAdviceList = CreditAdvice.findAll(paginationArgs) {
   ilike('id', "%$idFilter%")
   .....
   ilike('statusCode', statusCodeFilter)
}

You can style it differently, but basically you can build the pagination arguments first, and pass them to the findAll. No duplicated code, clearer responsability of the conditions. To clarify, I'm adding all the options and then filtering them to exclude the ones that are null.



来源:https://stackoverflow.com/questions/31532819/including-the-max-and-offset-criteria-inside-gorm-criteriabuilder-returns-an-err

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!