Grails初学者教程– Criteria API

本文介绍Grails框架中的Criteria API,一种用于数据库查询的优雅替代方案,提供了list、get、scroll等方法,支持AND、OR逻辑,分页查询,属性值比较等功能。

本教程将展示如何使用Criteria API从数据库中搜索数据。 Criteria是功能强大的API,是HQL的优雅替代方案。

介绍

一篇文章表明HQL是执行复杂查询的强大方法。 但是,如果HQL语句不固定并且需要连接,这不是很优雅。 例如:如果仅当参数不为null时才需要查询数据库,则我们的代码将如下所示:

def hqlQueryString = "from Person where 1 = 1"
def hqlNamedParams = [:]
if (firstNameToSearch != null) {
    hqlQueryString = hqlQueryString + ' and firstName = :firstNameToSearch '
    hqlNamedParams= hqlNamedParams + [firstNameToSearch:firstNameToSearch]
}
if (lastNameToSearch != null) {
    hqlQueryString = hqlQueryString + ' and lastName = :lastNameToSearch '
    hqlNamedParams= hqlNamedParams + [lastNameToSearch:lastNameToSearch]
}
def result = Person.executeQuery(hqlQueryString, hqlNamedParams)

如您所见,它可能很脏且难以维护。 它也容易出错。 条件是一种更优雅的选择。 新代码如下所示:

def criteria = Person.createCriteria()
def result = criteria.list {
    if (firstNameToSearch != null) {
        eq('firstName', firstNameToSearch)
    }
    if (lastNameToSearch != null) {
        eq('lastName', lastNameToSearch)
    }
}

现在,即使乍一看,该代码也更具可读性和易于理解。

准则方法

以下是条件实例的可用方法

清单

list方法将返回给定关闭条件的所有匹配行。

这将返回所有Person实例

def criteria = Person.createCriteria()
def result = criteria.list{}

这将返回所有名字为John的Person实例。

def criteria = Person.createCriteria()
def result = criteria.list{ 
    eq ('firstName', 'John')
}

得到

给定关闭条件, get方法将返回一行。 请注意,当条件匹配多于1行时, get将引发异常。 如果没有匹配的行,则返回空值。

此示例将获得驾驶执照的Person实例。

def criteria = Person.createCriteria()
def result = criteria.get{
    eq ('driverslicenseNo', 'C1922-8DFG-1155')
}

滚动

scroll方法将返回可滚动的结果集。 当您需要处理大量行时,这很有用,因为结果集将仅根据需要传输数据。

这是遍历姓氏为Doe的所有人的示例。

def criteria = Person.createCriteria()
def result = criteria.scroll{
    eq ('lastName', 'Doe')
}
while (result.next()) {
    def person = result.get()[0]
    println "Hello ${person.firstName} ${person.lastName}"
}

AND OR运算子

我们可以使用andor运算符来构造复杂的逻辑。

def criteria = Person.createCriteria()
def result = criteria.list {
    or {
        and {
            eq('lastName', 'Doe')
            gt('age', 15)
        }
        and {
            eq('lastName', 'Smith')
            gt('age', 18)
        }
    }
}

分页

我们可以通过传递offsetmax参数来执行分页。 max参数是要返回的最大行数,而offset参数是在检索第一个结果之前要跳过的行数。

如果我们希望一次检索10行,下面是检索第一页的代码:

def criteria = Person.createCriteria()
def result = criteria.list (max:10, offset:0) {
    eq ('firstName', 'John')
}

这是用于检索第二页的代码。 注意,唯一的区别是偏移量的值。

def criteria = Person.createCriteria()
def result = criteria.list (max:10, offset:0) {
    eq ('firstName', 'John')
}

这是使用firstResultmaxResults检索第一页和第二页的另一种方法

def criteria = Person.createCriteria()
def result = criteria.list {
    eq ('firstName', 'John')
    firstResult(0)
    maxResults(10)
}
def criteria = Person.createCriteria()
def result = criteria.list {
    eq ('firstName', 'John')
    firstResult(10)
    maxResults(10)
}

强烈建议在进行分页时使用sort by子句。 这是有关如何按姓氏排序的示例:

def criteria = Person.createCriteria()
def result = criteria.list {
    eq ('firstName', 'John')
    order('lastName', 'asc')
    firstResult(0)
    maxResults(10)
}

投影

可以控制查询的结果列。 例如:

def criteria = Person.createCriteria()
def result = criteria.list {
    projections {
        property('firstName')
        property('lastName')
    }
}

而不是具有人员实例列表,它将返回一个二维列表。 以下是有关如何使用结果数据的示例代码:

def firstPerson = result[0]
def firstName = firstPerson[0]
def lastName = firstPerson[1]
println "First Name = ${firstName}"
println "Last Name = ${lastName}"

汇总功能

与SQL相似,也可以在条件内使用聚合函数。

  • 独特 –这是一个有关如何检索数据库中所有唯一姓氏的示例
    def criteria = Person.createCriteria()
    def result = criteria.list {
        projections {
            distinct('lastName')
        }
    }
    println "Here are the list of unique last names"
    result.each { lastName ->
        println "${lastName}"
    }
  • 平均 -这是有关如何获得所有人平均年龄的示例
    def criteria = Person.createCriteria()
    def result = criteria.list {
        projections {
            avg('age')
        }
    }
    println "The average age is ${result[0]}"
  • count –这是有关如何获取人员表中记录数的示例
    def criteria = Person.createCriteria()
    def result = criteria.list {
        projections {
            count()
        }
    }
    println "The number of rows is ${result[0]}"
  • sum –这是有关如何使用sum的示例
    def criteria = Purchase.createCriteria()
    def result = criteria.list {
        projections {
            sum('price')
        }
    }
    println "The sum of all price ${result[0]}"
  • maxmin –这是如何使用max和min的示例
    def criteria = Person.createCriteria()
    def result = criteria.list {
        projections {
            max('age')
            min('age')
        }
    }
    println "The maximum age is ${result[0][0]}"
    println "The minimum age is ${result[0][1]}"

其他标准示例

以下是有关如何过滤结果的其他示例。

  • 属性值比较 –可以将域属性与特定值进行比较。 以下是一些相关标准: eqgtgeltlene
    以下是示例代码,列出了所有姓Doe的青少年:
    def criteria = Person.createCriteria()
    def result = criteria.list {
        eq('lastName', 'Doe')
        ge('age', 13)
        le('age', 17)
    }
  • 属性到属性比较 –可以将域属性与另一个属性进行比较。 以下是一些相关条件: eqPropertygtPropertygePropertyltPropertylePropertyneProperty
    这是一个示例代码,列出了所有与名字相同的人:
    def criteria = Person.createCriteria()
    def result = criteria.list {
        eqProperty('firstName', 'lastName')
    }
  • 测试null值isNullisNotNull可用于检查域属性是否为null。 这是一个示例,列出了所有没有名字编码的人:
    def criteria = Person.createCriteria()
    def result = criteria.list {
        isNull('firstName')
    }

有关其他条件,请参阅最新的Grails文档。

翻译自: https://www.javacodegeeks.com/2015/02/grails-tutorial-for-beginners-criteria-api.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值