如何在grails中的createCriteria中放入if语句?

时间:2016-02-29 13:19:51

标签: grails criteria hibernate-criteria

我是grails的新手,我遇到了问题。我有一个接收一些数据并将数据与createCriteria匹配并返回数据的方法。它运行正常,但我现在想要做的是如果匹配我在方法中的五个参数,如果匹配返回数据,如果不匹配五个参数,请尝试匹配四个参数并返回如果数据与四个参数不匹配,请尝试匹配三个并返回数据....

但是我不确定如何将所有这些放在if语句中并返回我的result.dataPerson,或者我必须找到另一种方法来实现它。

我的方法:

def getPersonData(String name, String surname, String address, String phone){


    def searchdataPerson = ClientConfig.createCriteria()
    def result = searchdataPerson.get{
        and{
            or{
                eq('surname', surname)
                isNull('surname')
            }
            or{
                eq('address', address)
                isNull('address')
            }
            or{
                eq('phone', phone)
                isNull('phone')
            }
            or{
                eq('name', name)
                isNull('name')
            }
        }
        maxResults(1)
    }

    return result.dataPerson
}

我试图做这样的事情,但它不起作用

def searchdataPerson = ClientConfig.createCriteria()
        def result = searchdataPerson .get{
            if(eq('name', name) && eq('surname', surname) && eq('address', address) && eq('phone', phone)){
            }else if(eq('name', name) && eq('surname', surname) && eq('address', address)){
            }       
            maxResults(1)
        }
return result.dataPerson

我收到此错误:

java.lang.NullPointerException: Cannot get property 'dataPerson' on null object

2 个答案:

答案 0 :(得分:2)

我无法从你的例子中看出你真正想要做什么,但你可以将if语句放在闭包的任何地方,正常的Groovy语言规则允许:

def getPersonData(String name, String surname, String address, String phone){


def searchdataPerson = ClientConfig.createCriteria()
def result = searchdataPerson.get{
    and{
        if(surname != 'GooglyMoogly') {
            or{
                eq('surname', surname)
                isNull('surname')
            }
        }
        if(address != 'Caddyshack') {
            or{
                eq('address', address)
                isNull('address')
            }
        }
        // ...
    }
    maxResults(1)
}

return result.dataPerson
}

答案 1 :(得分:0)

正如杰夫上面所指出的那样,你应该真正引用结果并且你得到了错误,因为你得到了一个结果但是然后试图返回一个实体或者事件对象挂起结果。

什么是dataPerson?是ClientConfig挂起的关系,即在ClientConfig中是belongsTo还是hasMany声明?

从以上所有内容来看,它并不完全清楚,但试图以另一种方式解释它,你可以使用HQL:

String  query="""
select new map(c.name as name,c.surname as surname, d as dataPerson)
 from ClientConfig c 


left join c.dataPerson d where 

(c.surname != 'GooglyMoogly' or c.surame is null or c.surname=:surname) and

(c.address != 'Caddyshack' or c.address is null or c.address=:address) and

(c.phone is null or c.phone=:phone) and
(c.name is null or c.name=:name) and

"""
def inputParams=[surname:surname,address:address,phone:phone,name:name]

       def result =  ClientConfig.executeQuery(query,inputParams,[readOnly:true,timeout:15,max:1])

    result?.each { output ->

  println "--- ${output?.name} ???? ${output.surname} ???? "

   output?.dataPerson.each { dp ->
      println "--- ${dp.name} ???? "
   }
}

上面的某些内容可能不正确,但可能会帮助您破译您想要达到的目标。

在上面的HQL语句中,我在clientConfig和dataPerson之间进行了左连接。这是假设

class ClientConfig {

   static hasMany= [dataPerson:DataPerson]
}

左连接意味着即使dataPerson不存在,它也会尝试加入(null对象)

当迭代时,如果我想要的只是挂起dataPerson的方面那么

 result?.each { output ->
   // if hasMany
     println "${output.dataPerson[0].name}"
   // if a belongsTo or a direct relation:
     println "${output.dataPerson.name}"
}

如果您定义了希望在HQL中收集的实际元素,那么为了省去这一点,那么您的最终迭代将仅包含您要求的内容,然后无需前进遍历类。

String  query="""
    select new map(d.name as name,d.surname as surname, d.address as address)
     from ClientConfig c 
...

现在你有了对象,不需要从result扩展到result.dataSet ....:

 result?.each { output ->
   println " $output.name $output.surname $output.address "
    }