Grails中的Where 查询

 where 方法,Grails 2.0被引入,构建在 Detached Criteria 之上,为普通查询提供了一个增强的运行时检查的查询DSLwhere 方法比动态查询更灵活,比criteria的代码更简洁而且为撰写查询提供了一个强大的机制。

基本查询

 where 方法接受一个闭包看起来非常类似于Groovy的规范集合方法。闭包用规范的Groovy语法定义一个逻辑条件。例如:

def query = Person.where {

   firstName == "Bart"

}

Person bart = query.find()

返回的对象是一个 DetachedCriteria 实例,这意味着他不语任何特定的数据库连接或会话相关联。意味着你可以使用 where在类层面去定义普通查询:

class Person {

    static simpsons = where {

         lastName == "Simpson"

    }

    …

}

Person.simpsons.each {

    println it.firstname

}

查询执行是懒加载,仅仅在使用 DetachedCriteria实例之后才发生。如果你要执行一个立即生效的where样式的查询,可以改用 findAll  find方法的来完成:

def results = Person.findAll {

     lastName == "Simpson"

}

def results = Person.findAll(sort:"firstName") {

     lastName == "Simpson"

}

Person p = Person.find { firstName =="Bart" }

每一个Groovy操作映射到一个常规的criteria方法。下表提供了一个Groovy操作映射方法的列示:

 

Operator

Criteria Method

Description

==

eq

Equal to

!=

ne

Not equal to

> 

gt

Greater than

< 

lt

Less than

>=

ge

Greater than or equal to

<=

le

Less than or equal to

in

inList

Contained within the given list

==~

like

Like a given string

=~

ilike

Case insensitive like

这使我们利用规范的Groovy比较操作符和逻辑来定制复杂的查询成为可能:

def query = Person.where {

    (lastName != "Simpson" &&firstName !="Fred") || (firstName =="Bart" && age > 9)

}

def results = query.list(sort:"firstName")

Groovy的正则表达式匹配操作符映射到likeilike查询。除非在表达式的右边是一个  Pattern 对象,这种情况下,他们映射到一个 rlike 查询:

def query = Person.where {

     firstName ==~ ~/B.+/

}

注意,只有底层数据库支持正则表达式, rlike 查询才会被支持。

一个 between 条件查询可以使用 in 关键词来组合一个。

def query = Person.where {

     age in 18..65

}

最后,你可以用null和标准的比较运算符来做 isNull isNotNull 样式查询:

def query = Person.where {

     middleName == null

}

查询组合

由于 where方法的返回值是一个 DetachedCriteria实例,你可以从原来的查询组合成新的查询:

def query = Person.where {

     lastName == "Simpson"

}

def bartQuery = query.where {

     firstName == "Bart"

}

Person p = bartQuery.find()

注意,你不能在where方法闭包中定义变量传递,除非他已经明确地被转换成了 DetachedCriteria 实例。也就是说下面的语句是错误的:

def callable = {

    lastName == "Simpson"

}

def query = Person.where(callable)

上面的代码必须这样写:

import grails.gorm.DetachedCriteria

def callable = {

    lastName == "Simpson"

} as DetachedCriteria<Person>

def query = Person.where(callable)

这如你所看到的,闭包定义是转换到 (使用Groovy as 关键字)一个在Person类中标记的 DetachedCriteria实例。

关联、分离和取反

就像前面提到的,你可以组合Groovy标准的逻辑运算符 (||  &&),形成关联和分离:

def query = Person.where {

    (lastName != "Simpson" &&firstName !="Fred") || (firstName =="Bart" && age > 9)

}

你还可以使用逻辑比较符!进行取反。

def query = Person.where {

    firstName == "Fred" &&!(lastName == 'Simpson')

}

属性比较查询

如果你在表达式的两边都是用属性名,那么相应的属性比较条件会被自动使用:

def query = Person.where {

   firstName == lastName

}

下表描述了每个比较操作映射到每个条件属性比较法:

Operator

Criteria Method

Description

==

eqProperty

Equal to

!=

neProperty

Not equal to

> 

gtProperty

Greater than

< 

ltProperty

Less than

>=

geProperty

Greater than or equal to

<=

leProperty

Less than or equal to

查询关联

关联可以被查询,使用点操作符来指定关联查询的属性名:

def query = Pet.where {

    owner.firstName == "Joe" ||owner.firstName =="Fred"

}

你可以将一组条件放进一个闭包方法中进行调用,在哪里,方法名匹配关联名:

def query = Person.where {

    pets { name == "Jack" || name == "Joe" }

}

这个技术可以结合其他顶层规范:

def query = Person.where {

     pets { name == "Jack" } || firstName=="Ed"

}

集合关联还可以用来查询集合的大小:

def query = Person.where {

       pets.size() == 2

}

下表显示了查询集合大小的标准比较运算符:

Operator

Criteria Method

Description

==

sizeEq

The collection size is equal to

!=

sizeNe

The collection size is not equal to

> 

sizeGt

The collection size is greater than

< 

sizeLt

The collection size is less than

>=

sizeGe

The collection size is greater than or equal to

<=

sizeLe

The collection size is less than or equal to

子查询

可能会在where查询中使用子查询。例如,找出所有年龄大于平均年龄的人:

final query = Person.where {

  age > avg(age)

}

下面是相关子查询的列表:

Method

Description

avg

The average of all values

sum

The sum of all values

max

The maximum value

min

The minimum value

count

The count of all values

property

Retrieves a property of the resulting entities

你可以使用of 方法申请添加条件到任何子查询,通过一个闭包来传递条件:

def query = Person.where {

  age > avg(age).of { lastName =="Simpson" } &&firstName =="Homer"

}

因为属性子查询返回多个结果,可以使用比较结果作为条件。例如,下面的例子查询一个比“simpson”年龄小的人。

Person.where {

    age < property(age).of {lastName =="Simpson" }

}

其他函数

有几个函数可以加入到你的查询内容中。列示如下:

Method

Description

second

The second of a date property

minute

The minute of a date property

hour

The hour of a date property

day

The day of the month of a date property

month

The month of a date property

year

The year of a date property

lower

Converts a string property to upper case

upper

Converts a string property to lower case

length

The length of a string property

trim

Trims a string property

目前函数只能应用于领域类的属性和关联,你不能在诸如子查询的结果中使用函数。

例如,下面的查询寻找所有在2011年出生的人:

def query = Pet.where {

    year(birthDate) == 2011

}

你还可以在关联中应用函数:

def query = Person.where {

    year(pets.birthDate) == 2009

}

批量更新和删除

由于每一个 where 方法调用返回一个 DetachedCriteria 实例,你可以使用 where 查询执行批量操作。例如,批量更新和删除。

例如,下面的查询将所有 lastName"Simpson"的人的lastName更新为"Bloggs"

def query = Person.where {

    lastName == 'Simpson'

}

inttotal = query.updateAll(lastName:"Bloggs")

注意,一个批量操作方面的限制是连接查询(查询查询关联)是不允许的。

批量删除记录你可以使用deleteAll 方法:

def query = Person.where {

    lastName == 'Simpson'

}

inttotal = query.deleteAll()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值