Grails:使用createCriteria进行搜索

时间:2016-10-14 11:33:14

标签: grails

我需要进行简单的搜索(下面是两个我的示例 - 简单域和控制器操作)。我想返回firstName,lastName或Car.carName(如searchPattern

)的用户列表
   class User {
        String firstName
        String lastName
        static hasMany = [car : Car]
    }

    class Car {
    User user
    String carName
    }

     def list(String search){
...
     def searchPattern = "%" + search + "%"
     def domains = User.createCriteria().list(max: max, offset: offset) {
                or {
                    like("firstName", searchPattern)
                    like("lastName", searchPattern)
                    car {
                       like("carName", searchPattern)
                       }

    }
    }

它返回不正确的结果 - 没有看到没有车的用户。你可以帮我修改它以便正确工作吗?非常感谢

3 个答案:

答案 0 :(得分:0)

试试这个:

car{
  or{
    isNull 'carName'
    like 'carName', searchPattern
  }
}

答案 1 :(得分:0)

首先,您需要正确设置域类关联。您似乎正在UserCar之间进行 has-many 关联。有两种变化:单向和双向。但是,您的实现不使用。假设您需要双向关联,您需要像这样修改Car类:

class Car {
    static belongsTo = [user: User]
    String carName
}

为清楚起见,由于User有许多Car s,因此值得多元化集合名称:

class User {
    String firstName
    String lastName
    static hasMany = [cars : Car]
}

有关关联的更多信息,您可以阅读有关该主题的my article

接下来,既然你想要User,即使他们没有Car,你也应该知道GORM内置的一个微妙的默认值:SQL数据库表是自动 INNER JOIN < / em>的编辑。正是这个 INNER JOIN 导致User s没有Car被忽略。要解决此问题,您需要将联接更改为 OUTER JOIN 。你可以这样做:

import static org.hibernate.sql.JoinType.*

def domains = User.createCriteria().list(max: max, offset: offset) {
    createAlias('cars', 'c', LEFT_OUTER_JOIN)

    or {
        like("firstName", searchPattern)
        like("lastName", searchPattern)
        like("c.carName", searchPattern)
        isNull("c.carName")
    }
}

如果我记得,别名的使用方式不同,因此c.carName。您可以阅读有关使用LEFT OUTER JOIN here的更多信息。

答案 2 :(得分:0)

非常感谢大家的帮助和有用的链接。这决定了我的问题:

    import org.hibernate.criterion.CriteriaSpecification
.....

    def domains = User.createCriteria().list(max: max, offset: offset) {
    createAlias('cars', 'c', CriteriaSpecification.LEFT_JOIN)

    or {
        like("firstName", searchPattern)
        like("lastName", searchPattern)
        like("c.carName", searchPattern)
    }