GORM 支持动态查询的概念。一个动态查询看起来像一个静态方法调用,但是这些方法并不实际存在于任何形式的代码级别。
相反,基于一个给定类的属性,一个方法可以在运行时自动神奇地与代码结合在一起使用。如下面关于Book 类的例子:
class Book {
String title
Date releaseDate
Author author
}
class Author {
String name
}
Book 类的属性有如 title, releaseDate 和 author. 这些都可以结合在方法表达式中使用 findBy 和findAllBy 方法:
def book = Book.findByTitle("The Stand")
book = Book.findByTitleLike("Harry Pot%")
book = Book.findByReleaseDateBetween(firstDate, secondDate)
book = Book.findByReleaseDateGreaterThan(someDate)
book = Book.findByTitleLikeOrReleaseDateLessThan("%Something%", someDate)
方法表达式
GORM中的方法表达是由前缀,比如findBy后面跟一个表达式,结合一个或多个属性组成。其基本形式是:
Book.findBy([Property][Comparator][Boolean Operator])?[Property][Comparator]
令牌标记中的 '?' 是可选的。每个comparator 根据查询性质改变。例如:
def book = Book.findByTitle("The Stand")
book = Book.findByTitleLike("HarryPot%")
上面的例子,第一个查询是相等查询,后面的查询多了一个Like 比较器,等价于一个 SQL like 表达式。
可能的比较器包括:
· InList - 在给定值的列表
· LessThan - 小于给定值
· LessThanEquals - 小于或等于给定值
· GreaterThan – 大于给定值
· GreaterThanEquals – 大于或等于给定值
· Like – 等价于一个 SQL like 表达式
· Ilike – 类似于一个Like, 不区分大小写
· NotEqual – 不等于
· Between – 两个值之间(需要两个参数)
· IsNotNull – 不为空值(不带参数)
· IsNull – 是一个空值 (不带参数)
注意,最后三个比较器需要不同数目的方法参数进行比较,请看下面的例子:
def now = new Date()
def lastWeek = now - 7
def book = Book.findByReleaseDateBetween(lastWeek, now)
books = Book.findAllByReleaseDateIsNull()
books = Book.findAllByReleaseDateIsNotNull()
布尔值 (AND/OR)
方法表达式也可以使用一个布尔运算符来合并两个或两个以上的表达式:
def books = Book.findAllByTitleLikeAndReleaseDateGreaterThan(
"%Java%", new Date() - 30)
在这种情况下,我们在查询之间使用And相连,以确保同时满足两个条件。你同样可以使用OR:
def books = Book.findAllByTitleLikeOrReleaseDateGreaterThan(
"%Java%", new Date() - 30)
只要你喜欢,你可以组合多个规则,但它们必须使用And或者Or。如果你需要组合 And 和 Or或者一个数字规则创建一个很长的方法名,可以使用 Criteria 或HQL 查询。
关联查询
关联也可以使用查询:
def author = Author.findByName("Stephen King")
def books = author ? Book.findAllByAuthor(author) : []
在这里,如果 Author 实例不为空,我们用它查询,已获得给定 Author的所有Book实例。
分页和排序
相同的分页排序可以在list方法中设定参数,也可以使用动态查询提供一个map作为最终的参数:
def books = Book.findAllByTitleLike("Harry Pot%",
[max: 3, offset: 2, sort: "title", order: "desc"])