使用GORM动态查找器查询数据库

本指南将说明如何使用GORM的动态查找器有效查询数据库

s马修·莫斯(Matthew Moss)

365bet地区版本 4.0.1

365bet地区培训

365bet地区培训由创建并积极维护365bet地区框架的人们开发和交付

入门

365bet地区在本指南中,您将更新365bet地区服务以更有效地查询数据库。服务方法当前从表中加载所有记录并在内存中搜索它们,您将更改这些方法以使用 动态发现者到处都更有效率

您将需要什么

要完成本指南,您将需要以下内容

  • 花些时间在你手上

  • 体面的文本编辑器或IDE

  • 安装了JDK或更高版本JAVA首页适当配置

如何完成指南

要开始,请执行以下操作

要么

365bet地区指南存储库包含两个文件夹

  • 初始365bet地区初始项目通常是一个简单的365bet地区应用程序,其中包含一些其他代码,可以帮助您快速入门

  • 完成一个完整的示例它是按照指南中介绍的步骤进行操作并将这些更改应用于文档的结果。初始

要完成指南,请转到初始

  • 光盘进入grails引导查询gorm动态查找器初始

并按照下一节中的说明进行操作

您可以直接前往完成的例子如果你光盘进入grails指导查询gorm动态查找器完成

测试服务

初始完成项目是365bet地区完整的365bet地区应用程序而是有365bet地区服务查询服务您将进行编辑,进行任何更改,都应努力确保在其中进行所有单元测试。QueryServiceSpec继续通过

运行单元测试

gradlew initial test启动Gradle Daemon后续构建会更快初始编译Java否源初始compileGroovy初始buildProperties初始processResources初始类初始compileTestJava否源初始compileTestGroovy初始processTestResources否来源初始testClasses初始测试BUILD SUCCESSFUL

以上是所有单元测试都通过的结果。可以在以下位置找到完整的HTML报告:
初始构建报告测试测试索引html.

如果对服务进行更改导致单元测试失败,您将看到类似以下的输出

gradlew test启动Gradle Daemon后续的构建会更快。由groovy lang引起的QueryServiceSpec groovy上的ConditionFailedWithExceptionError groovy演示QueryServiceSpec上的QueryServiceSpec gro上的MissingPropertyException由groovy lang引起出错执行任务初始测试的执行失败曾经失败的测试请参阅文件路径中的报告查询gorm动态查找器初始构建报告测试索引html尝试使用stacktrace选项运行以获取堆栈跟踪使用info或debug选项运行以获取更多日志输出BUILD FAILED

在这种情况下,请打开HTML报告文件以查看哪些测试失败以及为什么

本指南的目标是更新每个查询服务具有使用动态查找器的实现并且仍然传递所有QueryServiceSpec单元测试

更新服务

动态发现者365bet地区是在运行时生成的方法,尽管这些方法最初并不存在,365bet地区使用Groovy元编程钩子方法缺失属性缺失365bet地区识别您何时尝试调用365bet地区,然后将检查您使用的方法名称并生成包括相应数据库查询的适当实现

动态查找器的读取方式类似于英语命令,例如,如果我想查找平均持续时间在2分钟到30分钟之间的所有棋盘游戏,则可能看起来像这样

定义游戏游戏findAllBy平均持续时间30, 90)

本指南将探索通过更新以下版本中的所有方法来构建动态查找器的方法查询服务使用动态查找器的实现,使得新的实现继续通过所有的单元测试QueryServiceSpec.

按价值找一个

第一种更新方法是QueryService queryGame这需要一个参数现有代码将加载游戏域类,并搜索名称与参数匹配的单个实例。由于的财产游戏是独特的

游戏查询游戏名称游戏全部找到名字

所有财产游戏确实听起来像从数据库中提取所有实例到内存中那样听起来很糟糕。这种糟糕的实现在只需要一个实例时就提取了所有实例,这是效率很低的代码。让我们准确地获得我们想要的一个实例,即提供的一个实例使用动态查找器命名

每个动态查找器都以前缀开头。由于名称被限制为唯一,我们希望只查找一个游戏,因此我们可以使用如果找到一个或一个,它将返回匹配的实例空值如果找不到匹配项

也可以仅用于检索多个匹配实例中的第一个。但是,您应该考虑添加参数化查询使您的查询健壮

在确定前缀之后,我们需要该属性与游戏域类有一个通过使用驼峰式案例将属性名称附加到前缀而效率低下的实现所使用的属性,我们创建了动态查找器findByName查找所需的游戏这种情况下,应在感兴趣的领域类上调用此方法游戏因此,我们的动态查找器调用将是游戏findByName.

同时,我们向动态查找器方法添加属性名称我们还应该在动态查找器方法中添加一个参数呼叫在这种情况下,我们要使用由提供的参数queryGame方法所以最终有效的执行queryGame

游戏查询游戏名称游戏findByName名称

更改实现并运行测试以查看它们仍然通过

当您将属性名称附加到动态查找器方法时,您还要将相应的参数附加到方法调用绝大多数情况下在这方面的几种情况将在本指南的后面部分中指出。

通过价值发现许多

知道如何通过属性值查找一个实例,我们可以通过更改前缀而不是一个非唯一属性值来查找多个实例采用findAllBy返回匹配实例的列表,如果没有匹配的列表将为空

让我们更新QueryService queryGamesWithAverageDuration一种用于以提供的平均持续时间收集所有棋盘游戏的方法这是现有的低效实施

清单queryGamesWithAverageDuration整数averageDuration游戏全部findAllaverageDuration averageDuration

与以前一样,这种缓慢的实现将所有记录加载到内存中,然后对其进行搜索。如果仅返回匹配的记录,数据库引擎将更快,内存负载也将大大降低,因此我们将其更改为动态查找器

要查找多个记录,请使用findAllBy前缀追加属性名称平均持续时间为动态查找器方法名称的一致驼峰大小写更新大小写并传递平均持续时间来自的参数queryGamesWithAverageDuration作为动态查找器方法调用的参数

清单queryGamesWithAverageDuration整数averageDuration游戏findAllByAverageDuration averageDuration

按不平等查找

以前的方法通过值相等性搜索匹配的实例动态查找器还可以通过不等式搜索属性不等于是否大于或小于提供的值

让我们来看看QueryService queryGamesNotConsideredStrategy尝试查找根据数据库未标记为策略游戏的所有游戏

清单queryGamesNotConsideredStrategy游戏全部findAll战略
    }
}
将谓词写为IT策略但是对于这个演示,与明确表示以更好地说明低效版本与动态查找程序版本之间的相似性

由于我们希望会有一个以上的结果,因此我们仍然需要使用前缀findAllBy感兴趣的财产是战略布尔标志,但使用动态查找器findAllByStrategy true找到所有策略游戏,我们需要非策略游戏。为了找到那些策略游戏,我们需要添加一个比较器比较器将查询从相等性测试更改为其他查询,您将在后面的小节中看到许多查询。在这里,我们将使用比较器不平等当附加到动态查找器方法名称中的属性名称时,它会生成与非相等匹配的查询

然后,我们对查找非策略游戏的改进查询就是

清单queryGamesNotConsideredStrategy使用NotEqual比较器的一般情况游戏findAllByStrategyNotEqual)    (1)

    对布尔属性使用特殊形式的特殊情况游戏findAllNotStrategy(2)
}
1 该查询使用以下命令演示了动态查找器的一般形式:不平等比较器
2 该查询演示了特殊形式布尔属性的动态查找器
尽管此处显示的第二种形式更紧凑,更易读,但使用不平等比较器将对这里使用的带有布尔属性的任何数据库类型同样有效,只是为了演示比较器如何工作

如果我们想要大于或小于比较会怎么样?QueryService queryGamesExpectedShorterThan这将返回平均持续时间短于提供值的游戏列表

清单queryGamesExpectedShorterThan整数持续时间游戏全部findAll平均持续时间

至此,我们知道从findAllByAverageDuration由于我们要匹配的属性值是少于提供的值,我们应该使用少于比较器再次将此比较器附加在属性名称之后,因此我们最终改进的实现是

清单queryGamesExpectedShorterThan整数持续时间游戏findAllByAverageDurationLessThan超过持续时间

当您需要具有属性值的实例时,可以使用类似的比较器比...更棒提供的参数用途比...更棒例如QueryService queryGamesRatedMoreThan会找到所有评分高于提供的评分的游戏原始实现

清单queryGamesRatedMoreThan大十进制评分游戏全部findAll等级等级

我们针对此查询的动态查找器将称为findAllByRatingGreaterThan.

清单queryGamesRatedMoreThan大十进制评分游戏findAllBy评分高于评分

少于比...更棒比较器是严格不相等比较,即如果比较的值相等,则实例为被视为匹配项如果您还需要包括相等性,请使用非严格小于等于大于等于比较器

计数匹配实例

有时您不需要查询的实际结果,而只是需要多少个实例像以前一样,这种效率低下的实现会加载所有记录,然后计算有多少个谓词与匹配

整型queryHowManyGamesRatedAtLeast大十进制评分游戏全部计数等级等级

上述方法的更有效实现将称为动态查找器游戏findAllByRatingGreaterThanEquals评分然后返回结果列表的大小。但是,如果您只需要一个数字,那么匹配记录的数量就无法将数据库查询的结果提取到内存中

在这种情况下,请使用前缀它的工作原理非常像findAllBy但不是返回匹配的实例,而是返回匹配的实例数,因此要计算有多少游戏的额定值或更高

整型queryHowManyGamesRatedAtLeast大十进制评分游戏计数ByRatingGreaterThanEquals评分
到目前为止,您可能已经注意到查询服务365bet地区使用动态查找器有效实施的方法并不是真正有用的,也就是说365bet地区服务通常会执行本指南试图教导的更多业务逻辑。此处使用服务有助于将工作与测试分开

按值范围查找

如果您需要查找某些属性介于两个值之间的实例怎么办?也许您想知道域类代表的所有游戏比赛两个日期之间

清单queryMatchesPlayedBetweenDates日期开始日期日期finishDate匹配所有findAll startDate开始了开始finishDate

使用比较器之间之间是例外之一,它期望讨论下界和上限QueryService queryMatchesPlayedBetweenDates下限和上限是开始日期和结束日期

我们将使用开始了的财产比赛作为要检查的属性,我们可以选择查看完了属性,但在此期间可以为null开始了根据以下约束,不能为null比赛.

findAllBy寻找多个匹配的实例开始了作为要检查的财产,之间作为操作员在提供的上下限之间找到属性的值,这是有效的实现

清单queryMatchesPlayedBetweenDates日期开始日期日期完成日期匹配findAll开始于开始日期之间完成日期

类似的比较器是InRange之间

范围高分90..100
定义numHighScores queryService queryHowManyScoresWithinRange highScore

这是旧的低效实现queryHowManyScoresWithinRange:

整型queryHowManyScoresWithinRange范围范围得分全部计数得分了范围

由于我们只想知道有多少高分而不是分数本身,我们将使用得分了的属性得分了域类,我们将使用InRange与提供的范围进行比较这是改进的实现

整型

按相似字符串查找

除了对数字和日期等类型进行不等式比较之外,我们还希望进行不精确的字符串比较,以了解一个字符串与另一个字符串相似或相似。下面是三个示例,我们应该使用动态查找器进行改进

首先找到所有具有特定姓氏的玩家

清单queryPlayersWithLastName姓氏播放器全部findAll名称结尾为" ${}"
    }
}

GORM提供动态取景器比较器喜欢%在搜索字符串中作为通配符,因此上述内容可以更有效地写为

清单queryPlayersWithLastName姓氏播放器findAllByNameLike"% ${}")
}

%通配符可以在搜索字符串中的任意位置前后前后中间甚至多个位置它可以匹配任何字符串甚至空

第二个示例查找名称包含不区分大小写的文本片段的所有游戏机制

清单queryMechanics包含文本Mechanic全部findAll StringUtils containsIgnoreCase名称文字

较早的比较器喜欢区分大小写,它匹配任何%通配符出现,但其他文本完全匹配如果您要搜索忽略大小写,请使用我喜欢比较器您仍然可以像此处一样使用通配符

清单queryMechanics包含文字技工findAllByNameIlike"%${文本}%")
}

在第三个示例中,我们找到名称匹配正则表达式模式的所有游戏

清单queryGamesMatching模式游戏全部findAll名称模式
常用表达是开发人员以紧凑的形式定义复杂搜索表达式的便捷工具,Groovy提供支持正则表达式建立在Java中的正则表达式API.

要进行正则表达式匹配,请使用Rlike动态查找器中的比较器

清单queryGamesMatching模式游戏findAllByNameRlike模式Rlike不受普遍支持
}
Rlike比较器不受普遍支持仅当基础数据库支持正则表达式时才支持比较器如果数据库不支持正则表达式则Rlike会回落到喜欢行为

按零查找非零

365bet地区由于我们的数据库和365bet地区域类可以包含可能包含null值的属性,因此我们需要查询这些情况的方法。例如,在我们的原始服务实现中,我们有两种方法可用于查找哪些游戏已完成且哪些游戏仍在进行中

整型queryHowManyMatchesInProgress匹配所有计数完了空值
    }
}

整型queryHowManyMatchesCompleted匹配所有计数完了空值
    }
}

用于检查空值的比较器是一片空白IsNotNull这些特殊之处在于它们不需要动态查找器的参数。这是改进的实现

整型queryHowManyMatchesInProgress匹配计数ByFinishedIsNull整型queryHowManyMatchesCompleted匹配计数ByFinishedIsNotNull

在列表中查找物业

在以上各节中,我们已经能够通过属性按相等性按不等式按边界之间的值查找实例从提供的列表中使用InList比较器

这是两个示例,第一个查找所有游戏与以下列表匹配的记录游戏名称,而第二个示例查找所有名称比赛记录所列出游戏的玩法的记录

    清单queryGamesForNames清单<名称游戏全部findAll那么名字清单queryMatchesForGames清单游戏全部匹配findAll游戏游戏

通过使用InList比较器并传递要匹配的项目列表,我们可以减少这些方法的效率

    清单queryGamesForNames清单<名称游戏findAllByNameInList名称清单queryMatchesForGames清单游戏匹配findAllByGameInList游戏

在第二个例子中QueryService queryMatchesForGames请注意,列表不包含简单的类型,例如要么但实际上包含游戏域对象这是合理的,因为该属性游戏比赛 是...的实例游戏.

每当您有这样的关系时,都可以将域类实例用作查询的一部分。得分了域引用了播放器域,例如查找特定玩家的所有比分

    定义jeffBrown Player findByName'杰夫·布朗')
    定义分数分数findByPlayer jeffBrown

相关的InList比较器是NotInList听起来很像的比较器会找到匹配的实例,其中被测属性为在提供的列表中找到因此,对于效率低下的实现QueryService queryGamesOtherThan:

    清单queryGamesOtherThan清单游戏游戏全部findAll 游戏

可以使用NotInList比较器

    清单queryGamesOtherThan清单游戏游戏findAllByNameNotInList游戏名称

组合查询子句

有时候,您想查找多个属性的记录,让我们举个例子,我们要查找支持一定数量玩家的所有棋盘游戏。我们效率低下的实现看起来像这样

    整型queryHowManyGamesSupportPlayerCount整数playerCount游戏全部计数mi玩家数玩家数maxPlayers

这些实现使用相等且小于或等于运算符,我们已经知道如何独立搜索这些东西,例如,查找最小玩家数不高于所请求玩家数的地方,我们将执行此操作

    清单游戏游戏findAllBy最低玩家数少于等于玩家数

或寻找最大玩家人数不少于要求玩家人数的游戏,我们会这样做

    清单游戏游戏findAllBy MaxPlayers大于平等人数

因为minPlayersmaxPlayers是不同的属性,我们不能使用之间要么InRange比较器,因为它们在单个属性上运行

相反,我们在这里介绍组合器这些是布尔运算符要么如果我们要求两个要求都通过或要么如果只需要一个通过

对于我们当前的示例,我们想结合findAllByMinPlayersLessThanEqualfindAllByMaxPlayersGreaterThanEqual要求传递两个与布尔值和运算符匹配的语句&&findAllBy只需要指定一次,那么我们的组合查询变为findAllByMinPlayersLessThanEqualAndMaxPlayersGreaterThanEqual最后的动态finder方法调用将采用两个参数,其中一个用于minPlayers还有一个maxPlayers.

    整型queryHowManyGamesSupportPlayerCount整数playerCount游戏计数ByMinPlayersLessThanEqualsAndMaxPlayersGreaterThanEquals playerCount playerCount

另一个类似的示例找到所有支持确切数量玩家的棋盘游戏,例如minPlayersmaxPlayers等于相同的数字原始实现

    清单queryGamesSupportExactPlayerCount整数mi玩家人数maxPlayers playerCount

以及改进的实施

    清单queryGamesSupportExactPlayerCount整数
您不仅可以在动态查找器中使用两个谓词,还可以使用多次连接所需的谓词,即查询所需的条件。但是,在过去的两个或三个谓词中,您可能会发现您的动态查找程序变得难以阅读,通过使用可以更清晰地实现复杂的查询其他查询技术这些将是未来指南的主题

如果我们不要求组合的一部分通过,我们可以使用要么与布尔值或运算符进行比较的组合器||QueryService queryGamesConsideredFamilyOrParty

    清单queryGamesConsideredFamilyOrParty Game全部findAll家庭派对

可以用改进的实现方式代替

    清单queryGamesConsideredFamilyOrParty游戏findAllByFamilyOrParty, )
    }
虽然动态取景器可以使用任意数量的组合器或任意数量的要么组合你不能采用要么一起在同一动态查找器中,所以此查询及其类似查询无效游戏findByMinPlayersAndMaxPlayersOrParty true要指定这样的条件,您需要使用其他查询技术.

参数化查询

对结果进行排序和分页时,任何数据库查询都将变得更加有用。地图可以添加参数来管理排序和分页此参数映射与清单方法

分类, 订购ignoreCase.

  • 分类指定用于对所有实例进行排序的属性

  • 订购是一个字符串,它指定排序是否应递增ASC或下降递减描述).

  • ignoreCase指定在排序期间是否应忽略大小写

要在查询中分页结果,请使用最大值.

  • 指定要返回的第一个结果的索引

  • 最大值指定要返回的最大结果数

分页参数被应用排序参数

例如,假设我要查找所有支持至少两个玩家的策略游戏

    清单, 2)

现在让我们对其进行修改以对结果进行排序,以首先显示支持最大最大玩家数的游戏。由于我们正在更改排序,而不是要包含在结果中的条件,因此我们添加了分类/订购查询参数

    清单, 2, [分类: 'maxPlayers', 订购: '描述'])

接下来,让我们仅显示第一组的十个结果/最大值参数

    清单, 2, [分类: 'maxPlayers', 订购: '描述', : 0, 最大值: 10])

假设该应用的用户点击了下一个按钮,我们可以修改最后一次通话,以通过更新

    清单, 2, [分类: 'maxPlayers', 订购: '描述', : 10, 最大值: 10])

最后,如前所述更早前缀将返回查询的第一个匹配结果。对于健壮的代码,您应该考虑添加一个分类参数甚至替换findAllBy和使用最大值在您的参数中,例如

    这个游戏bestTwoPlayer游戏游戏findByMinPlayerAndMaxPlayer2, 2, [分类: '评分', 订购: '描述'])

    相当于这个
    清单bestTwoPlayerGame游戏findAllByMinPlayerAndMaxPlayer2, 2, [分类: '评分', 订购: '描述', 最大值: 1])
除了此处列出的参数外,还有更多可用参数。请参考文档以获取更多信息。清单看看它们是否适用于您的情况

方便的特殊形式

动态查找器是用于构建简单的数据库查询的出色工具,几乎没有麻烦,可读性强,效率高。除了前面几节中描述的所有可能性之外,还有一些特殊的便捷表单可以添加到您的工具箱中

查询然后创建保存

通常,开发人员将需要查询数据库以查看是否存在特定实例,以及是否不希望创建或保存该特定实例,然后再执行其他工作?

    定义类别类别findByName'僵尸')
    如果类别类别类别: '僵尸'分类保存齐平: )
    }
    现在对类别进行一些有用的操作

    定义游戏游戏findByNameAndMinPlayersAndMaxPlayers'', 2, 20)
    如果游戏游戏游戏: '', minPlayers: 2, maxPlayers: 20)
    }
    现在做一些有用的游戏

GORM为动态查找器提供了两个前缀,有助于消除这种样板基金rC联络人findOrSaveBy这两种方法都尝试使用指定的查询来查找匹配的实例。如果找到则返回该实例。如果找不到,则创建新实例,并使用名为属性值的查询设置其属性。findOrSaveBy使用实例也被保存,以下等同于上面

类别类别类别findOrSaveByName'僵尸'游戏游戏游戏findOrCreateByNameAndMinPlayersAndMaxPlayers'', 2, 20)

经常基金rC联络人如果您需要填写其他属性以建立关系或在保存之前确保满足某些约束,则可能更合适。基金rC联络人确实保存,所以打电话在实例上以保留您的更改

使用前缀时基金rC联络人findOrSaveBy仅允许完全匹配,因为如果找不到,则动态查找程序将尝试使用查询中提供的值来创建新实例。游戏findOrCreateByRating是有效但正在创建的动态查找器游戏findOrCreateByRatingGreaterThan不是

简化布尔匹配

以前,我们看到您可以通过实例的布尔属性来匹配实例,例如这些示例

    查找所有策略游戏游戏findAllBy策略)

    查找所有非派对游戏游戏findAllByPartyNotEqual)

    找到所有家庭游戏至少支持四名玩家, 4)

通过将属性名称合并到前缀中并删除相应的参数,可以缩短具有布尔值属性作为查询一部分的动态查找器,因此上述示例可以简化为

    查找所有策略游戏游戏findAllStrategy查找所有非派对游戏游戏findAllNotParty找到所有家庭游戏至少支持四名玩家游戏找到所有家庭均由最小玩家大于等于4)

如果仅检查布尔属性,则可以删除通过前缀的一部分,所以findAllByBooleanProperty变成findAllBooleanProperty).

检查一个值使用附加到的属性名称找到所有同时检查一个值使用附加到的属性名称findAllNot.

如果您还有其他条件,例如上面的第三个示例,请在后面附加这些条件通过在前面的前缀中

只要可以通过这种方式将boolean属性合并到前缀中。游戏findAllStrategyByFamily true查找所有既考虑策略又考虑家庭的游戏

与分离的标准和命名查询链接

尽管动态查找器对于简单查询非常方便,但更复杂的查询将需要其他技术。尽管此处不讨论这些高级查询技术,但通过以下方式进一步限制这些高级技术的结果可能会很有用。链式我将动态查找器附加到他们

例如,让我们找到所有使用的涉及到“手部管理”机制的游戏,并且平均持续时间少于几分钟。使用特定机制查找所有游戏可以通过以下方式完成:游戏域类命名查询, gamesWithMechanic.

    静态的名为Queries gamesWithMechanic a机械力学方程式'ID'机械师编号使用手掌管理游戏机制查找所有游戏机械师m机械师findByName"手部管理")
    定义游戏游戏游戏WithMechanic m

要查找平均时长少于几分钟的游戏,我们知道可以使用该通话游戏findAllByAverageDurationLessThan但这搜索所有几分钟之内即可完成游戏,而无需考虑游戏机制,要查找同时符合这两种条件的游戏,请将动态查找程序附加到命名查询中

    清单queryGamesWithMechanicNoLongerThanDuration Mechanic Mechanic整型持续时间游戏提供了一个命名查询gamesWithMechanic来查找所有使用提供的游戏机制的游戏
        可以将动态查找器链接到命名查询以缩小结果范围具有机械技工的游戏找到所有持续时间平均持续时间少于持续时间的游戏

类似地,可以将动态查找器附加到独立标准哪里查询进一步限制条件查询的结果

    清单queryGamesInCategoryWithAverageDuration类别类别整型持续时间这是在特定类别中查找所有游戏的独立标准分离标准分离标准DetachedCriteria游戏构建类别eq'ID'类别编号可以将动态查找器链接到分离的条件上以缩小结果范围detachedCriteria findAllByAverageDuration持续时间
    定义类别类别findByName"经济")
    定义游戏查询GamesInCategoryWithAverageDuration类别120)
365bet地区这些各种更先进的技术称为“查询”,其中“查询标准”和“分离的标准”将在未来的《 365bet地区指南》中进行深入探讨。

动态查找器摘要

前缀

在这些前缀中表示域类的某些布尔属性,将其替换为要测试的布尔属性的名称

字首 目的

查找与查询匹配的单个实例

findAllBy

查找与查询匹配的多个实例

基金rC联络人

如果找不到现有的匹配项,则特殊形式将创建一个新实例

findOrSaveBy

如果找不到现有的匹配项,则特殊形式将创建并保存一个新实例

findAllFlag通过

布尔属性的特殊形式将查找命名属性为true的所有实例追加依据以扩展查询

findAllNotFlag通过

布尔属性的特殊形式可查找命名属性为false的所有实例追加依据以扩展查询

比较器

在下表中关闭表示域类的某些属性,将其替换为要测试的实际属性的名称。小时或与要比较的实际值相似

比较器 等效Groovy代码 目的

findAllByProp val

近好

测试属性等于值

不平等

findAllByPropNotEqual val

近好

测试属性不等于值

少于

findAllByPropLessThan val

近好

小于等于

findAllByPropLessThanEquals val

近好

测试属性小于或等于值

比...更棒

findAllByPropGreaterThan val

近好

测试属性大于值

大于等于

findAllByPropGreaterThanEquals val

近好

测试属性大于或等于值

之间

findAllByPropBetween lowerVal upperVal

lowerVal prop道具upperVal

Tests属性介于lowerVal和upperVal之间,需要两个参数

InRange

findAllByPropInRange val

价值

测试属性在val所指定的范围内范围类型

喜欢

findAllByPropLike val

没有确切的等价于用val结束道具, 道具从瓦尔开始, 取决于搜索字符串

使用通配符字符串比较测试属性匹配%通配符区分大小写

我喜欢

findAllByPropIlike val

如同喜欢.

如同喜欢但不区分大小写

Rlike

findAllByPropRlike val

近好

使用正则表达式测试属性匹配

一片空白

findAllByPropIsNull

道具null

Tests属性为null,不需要任何参数

IsNotNull

findAllByPropIsNull

道具null

Tests属性不为null不需要参数

合路器

在单个动态查找器方法名称中,您可以使用要么要么多次合并多个条件,但不能同时使用要么在同一个动态取景器中

结合 等效Groovy代码 目的

findByNameAndYearLessThan Foo

命名Foo年

两个表达式必须匹配,实例才能匹配

要么

年龄

至少一个表达式必须匹配,实例才能匹配

参量

分页和排序是通过添加最终的地图任何动态查找器的参数该映射可能包含以下参数

参数 目的 默认

分类

所有匹配的实例均根据指定的属性进行排序之前最大值应用参数

如果未指定结果未排序,则没有默认值

订购

将排序顺序设置为升序或升序ASC或下降递减描述).

ASC

ignoreCase

如果排序不区分大小写区分大小写.

来自所有匹配的排序实例指定要返回的第一个实例的索引用于分页结果

0

最大值

来自所有匹配的排序实例最大值指定要返回的实例数的上限,用于分页结果

如果未指定,则没有默认值,将返回所有结果

例如,以下内容查找所有平均时长在到分钟之间的游戏,按其平均时长排序排序averageDuration从最长的顺序desc开始,仅返回前五个最大偏移结果

游戏findAllByAverageDurationInRange排序averageDuration顺序desc offset max

您需要365bet地区帮助吗

OCI赞助了本指南的创建OCI提供了几种365bet地区服务:

免费咨询

OCI 365bet地区团队包括365bet地区联合创始人Jeff Scott Brown和Graeme Rocher检查我们的365bet地区课程并向发展和维护365bet地区的工程师学习

Grails OCI团队