Spring Data Commons 示例查询
原标题:Spring认证|Spring Data Commons 示例查询
6.1. 介绍
本章介绍了 Query by Example 并解释了如何使用它。
示例查询 (QBE) 是一种用户友好的查询技术,具有简单的界面。它允许动态创建查询,并且不需要您编写包含字段名称的查询。事实上,Query by Example 根本不需要您使用特定于商店的查询语言编写查询。
6.2. 用法
Query by Example API 由三部分组成:
探针:具有填充字段的域对象的实际示例。
ExampleMatcher:ExampleMatcher包含有关如何匹配特定字段的详细信息。它可以在多个示例中重复使用。
Example: AnExample由探针和ExampleMatcher. 它用于创建查询。
Query by Example 非常适合以下几个用例:
使用一组静态或动态约束查询您的数据存储。
频繁重构域对象而不必担心破坏现有查询。
独立于底层数据存储 API 工作。
Query by Example 也有几个限制:
不支持嵌套或分组的属性约束,例如firstname = ?0 or (firstname = ?1 and lastname = ?2).
仅支持字符串的开始/包含/结束/正则表达式匹配以及其他属性类型的精确匹配。
在开始使用 Query by Example 之前,您需要有一个域对象。首先,为您的存储库创建一个接口,如以下示例所示:
示例 69.示例 Person 对象
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
private Address address;
// … getters and setters omitted
}
前面的示例显示了一个简单的域对象。您可以使用它来创建Example. 默认情况下,null忽略具有值的字段,并使用商店特定的默认值匹配字符串。
将属性包含在 Query by Example 标准中是基于可空性。除非忽略属性路径,否则始终包含使用原始类型 ( int, double, ...)的属性。
可以使用of工厂方法或使用ExampleMatcher. Example是不可变的。以下清单显示了一个简单的示例:
示例 70. 简单示例
Person person = new Person();
person.setFirstname("Dave");
Example example = Example.of(person);
创建域对象的新实例。
设置要查询的属性。
创建Example.
您可以使用存储库运行示例查询。为此,让您的存储库接口扩展QueryByExampleExecutor. 以下清单显示了QueryByExampleExecutor界面的摘录:
例 71. QueryByExampleExecutor
public interface QueryByExampleExecutor {
S findOne(Example example);
Iterable findAll(Example example);
// … more functionality omitted.
}
6.3. 示例匹配器
示例不限于默认设置。您可以使用 为字符串匹配、空值处理和特定于属性的设置指定自己的默认值ExampleMatcher,如以下示例所示:
示例 72. 具有自定义匹配的示例匹配器
Person person = new Person();
person.setFirstname("Dave");
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("lastname")
.withIncludeNullValues()
.withStringMatcher(StringMatcher.ENDING);
Example example = Example.of(person, matcher);
创建域对象的新实例。
设置属性。
创建一个ExampleMatcher以期望所有值匹配。即使没有进一步的配置,它也可以在这个阶段使用。
构造一个新ExampleMatcher的忽略lastname属性路径。
构造一个 newExampleMatcher以忽略lastname属性路径并包含空值。
构造一个 newExampleMatcher来忽略lastname属性路径,包含空值,并执行后缀字符串匹配。
创建一个新的Example基于域对象和配置上ExampleMatcher。
默认情况下,ExampleMatcher期望在探测器上设置的所有值都匹配。如果要获得与任何隐式定义的谓词匹配的结果,请使用ExampleMatcher.matchingAny().
您可以为单个属性指定行为(例如“名字”和“姓氏”,或者对于嵌套属性,“address.city”)。您可以使用匹配选项和区分大小写来调整它,如以下示例所示:
示例 73. 配置匹配器选项
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("firstname", endsWith())
.withMatcher("lastname", startsWith().ignoreCase());
}
另一种配置匹配器选项的方法是使用 lambdas(在 Java 8 中引入)。这种方法创建了一个回调,要求实现者修改匹配器。您不需要返回匹配器,因为配置选项保存在匹配器实例中。以下示例显示了使用 lambda 的匹配器:
示例 74. 使用 lambda 配置匹配器选项
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("firstname", match -> match.endsWith())
.withMatcher("firstname", match -> match.startsWith());
}
Example使用配置的合并视图创建的查询。默认匹配设置可以在ExampleMatcher级别设置,而单独的设置可以应用于特定的属性路径。已设置上的设置ExampleMatcher由属性路径设置继承,除非它们被明确定义。属性补丁上的设置比默认设置具有更高的优先级。下表描述了各种ExampleMatcher设置的范围: