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

How can I put an if statement inside of a createCriteria in grails?

我是 grails 新手,遇到了问题。我有一个方法可以接收一些数据并将数据与 createCriteria 和 return 数据相匹配。它工作正常,但我现在想做的是,如果与方法中的五个参数匹配,如果匹配 return 数据,如果与五个参数不匹配,则尝试与四个参数匹配和 return 数据,如果与四个参数不匹配,请尝试与三个和 return 数据匹配....

但不太确定如何将所有这些放在 if 语句和 return 我的 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

我无法从你的示例中看出你真正想做什么,但你可以将 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
}

正如 Jeff 在上面指出的那样,您确实应该参考结果,而您收到错误是因为您正在获得结果,但随后试图 return 一个实体或事件对象挂起结果。

什么是数据人?它是 ClientConfig 的关系,即 belongsTo 或 ClientConfig 中的 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 不存在,它也会尝试连接(空对象)

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

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

如果您在 HQL 中定义了您希望收集的实际元素,那么为了节省执行任何这些操作,那么您的最终迭代将仅包含您所要求的内容,然后就无需向前走通过 class.

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

您现在在这里有对象,无需从结果扩展到 result.dataSet ....:[=​​15=]

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