示例查询

介绍

本章介绍了示例查询,并解释了如何使用它。spring-doc.cadn.net.cn

示例查询(QBE)是一种用户友好的查询技术,界面简单。 它支持动态查询创建,且不需要编写包含字段名称的查询。 事实上,示例查询并不要求你使用商店特定的查询语言来编写查询。spring-doc.cadn.net.cn

本章解释了“示例查询”的核心概念。 这些信息取自Spring Data Commons模块。 根据你的数据库,字符串匹配支持可能有限。

用法

示例查询API由四个部分组成:spring-doc.cadn.net.cn

  • 探测:带有填充字段的域对象的实际示例。spring-doc.cadn.net.cn

  • ExampleMatcher:这ExampleMatcher包含如何匹配特定字段的详细信息。 它可以在多个示例中重复使用。spring-doc.cadn.net.cn

  • 示例:一示例由探针和ExampleMatcher. 它用于创建查询。spring-doc.cadn.net.cn

  • FetchableFluentQuery:一个FetchableFluentQuery提供流畅的API,允许对源自示例. 使用 Fluent API 可以让你为查询指定排序、投影和结果处理。spring-doc.cadn.net.cn

示例查询适用于多种用例:spring-doc.cadn.net.cn

示例查询还有若干局限性:spring-doc.cadn.net.cn

在开始使用示例查询之前,你需要有一个域对象。 要开始,请为你的仓库创建一个界面,如下示例所示:spring-doc.cadn.net.cn

示例人物对象
public class Person {

  @Id
  private String id;
  private String firstname;
  private String lastname;
  private Address address;

  // … getters and setters omitted
}

前面的例子展示了一个简单的领域对象。 你可以用它来创建一个示例. 默认情况下,字段具有值被忽略,字符串通过存储的特定默认值进行匹配。spring-doc.cadn.net.cn

属性包含在示例查询标准中基于可空性。 使用原始类型的性质(智力,, …)除非ExampleMatcher忽略属性路径.

示例可以通过以下几个方法构建工厂方法或使用ExampleMatcher.示例是不可改变的。 以下列表展示了一个简单的示例:spring-doc.cadn.net.cn

例子1。简单示例
Person person = new Person();                         (1)
person.setFirstname("Dave");                          (2)

Example<Person> example = Example.of(person);         (3)
1 创建一个新的域对象实例。
2 将属性设置为查询。
3 创建示例.

你可以通过使用仓库来运行示例查询。 为此,可以让你的仓库接口扩展QueryByExampleExecutor<T>. 以下列表展示了以下内容的摘录QueryByExampleExecutor接口:spring-doc.cadn.net.cn

QueryByExampleExecutor
public interface QueryByExampleExecutor<T> {

  <S extends T> S findOne(Example<S> example);

  <S extends T> Iterable<S> findAll(Example<S> example);

  // … more functionality omitted.
}

示例匹配器

示例不仅限于默认设置。 你可以自定义字符串匹配、空处理和属性特定设置的默认设置,方法是使用ExampleMatcher如下例所示:spring-doc.cadn.net.cn

例子2。带有自定义匹配的示例匹配器
Person person = new Person();                          (1)
person.setFirstname("Dave");                           (2)

ExampleMatcher matcher = ExampleMatcher.matching()     (3)
  .withIgnorePaths("lastname")                         (4)
  .withIncludeNullValues()                             (5)
  .withStringMatcher(StringMatcher.ENDING);            (6)

Example<Person> example = Example.of(person, matcher); (7)
1 创建一个新的域对象实例。
2 设置属性。
3 创建一个ExampleMatcher期望所有数值都匹配。 即使没有进一步配置,目前仍可使用。
4 构建一个新的ExampleMatcher忽略姓氏财产路径。
5 构建一个新的ExampleMatcher忽略姓氏属性路径,并包含空值。
6 构建一个新的ExampleMatcher忽略姓氏属性路径,包含空值,并执行字符串后缀匹配。
7 创建一个新的示例基于域对象和配置ExampleMatcher.

默认情况下,ExampleMatcher期望探针上设置的所有值都匹配。 如果你想得到与任何隐式定义的谓词匹配的结果,可以用示例Matcher.matchingAny().spring-doc.cadn.net.cn

你可以为单个属性指定行为(比如“名字”和“姓氏”,嵌套属性则是“address.city”)。 你可以根据匹配选项和大小写敏感度进行调整,如下示例所示:spring-doc.cadn.net.cn

配置匹配器选项
ExampleMatcher matcher = ExampleMatcher.matching()
  .withMatcher("firstname", endsWith())
  .withMatcher("lastname", startsWith().ignoreCase());
}

配置匹配器选项的另一种方法是使用 lambda(Java 8 引入)。 这种方法会生成一个回调,要求实现者修改匹配器。 你无需返回匹配器,因为配置选项保留在匹配器实例中。 以下示例展示了使用 lambda 的匹配器:spring-doc.cadn.net.cn

用lambda配置匹配器选项
ExampleMatcher matcher = ExampleMatcher.matching()
  .withMatcher("firstname", match -> match.endsWith())
  .withMatcher("firstname", match -> match.startsWith());
}

示例使用合并视图来展示配置。 默认匹配设置可以在ExampleMatcher而个别设置可以应用于特定的物业路径。 设置为ExampleMatcher除非属性路径设置被明确定义,否则会继承。 属性补丁上的设置优先级高于默认设置。 下表描述了各类的范围ExampleMatcher设置:spring-doc.cadn.net.cn

表1。范围ExampleMatcher设置
设置 范围

空处理spring-doc.cadn.net.cn

ExampleMatcherspring-doc.cadn.net.cn

字符串匹配spring-doc.cadn.net.cn

ExampleMatcher以及性质路径spring-doc.cadn.net.cn

忽略性质spring-doc.cadn.net.cn

性质路径spring-doc.cadn.net.cn

大小写区分spring-doc.cadn.net.cn

ExampleMatcher以及性质路径spring-doc.cadn.net.cn

价值转换spring-doc.cadn.net.cn

性质路径spring-doc.cadn.net.cn

Fluent API

QueryByExampleExecutor还有一种方法,我们之前还没提到:<S 扩展 T, R>R findBy(example<S>例,Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction). 与其他方法一样,它执行由示例. 然而,通过第二个参数,你可以控制执行中那些你无法动态控制的部分。 你通过调用各种方法来实现FetchableFluentQuery在第二个论点中。排序它让你为结果指定排序。你可以指定你想将结果转换成哪种类型。项目限制被查询属性。第一,第一个值,,一值,,,,,计数存在定义你得到的结果类型以及当可用结果数量超过预期时查询的行为。spring-doc.cadn.net.cn

使用流流API获取最后一个可能的多个结果,按姓氏排序。
Optional<Person> match = repository.findBy(example,
    q -> q
        .sortBy(Sort.by("lastname").descending())
        .first()
);

在 Spring Data JPA 中,你可以使用带仓库的示例查询,如下示例所示:spring-doc.cadn.net.cn

例子3。使用仓库的示例查询
public interface PersonRepository extends JpaRepository<Person, String> { … }

public class PersonService {

  @Autowired PersonRepository personRepository;

  public List<Person> findPeople(Person probe) {
    return personRepository.findAll(Example.of(probe));
  }
}
目前,只有奇点属性属性可以用于属性匹配。

属性指定符接受属性名称(例如名称姓氏).你可以通过用点串联属性来导航 (地址.city).你还可以用匹配选项和大小敏感度来调整。spring-doc.cadn.net.cn

下表展示了各种字符串匹配器你可以使用的选项以及在一个名为名称:spring-doc.cadn.net.cn

表2。字符串匹配器选项
匹配 逻辑结果

默认值(大小写区分)spring-doc.cadn.net.cn

名字 = ?0spring-doc.cadn.net.cn

默认值(不区分大小写)spring-doc.cadn.net.cn

LOWER(名字)= LOWER(?0)spring-doc.cadn.net.cn

确切(大小写区分)spring-doc.cadn.net.cn

名字 = ?0spring-doc.cadn.net.cn

确切(不区分大小写)spring-doc.cadn.net.cn

LOWER(名字)= LOWER(?0)spring-doc.cadn.net.cn

开始(大小写区分)spring-doc.cadn.net.cn

名字像?0 + '%'spring-doc.cadn.net.cn

开始(不区分大小写)spring-doc.cadn.net.cn

LOWER(名字)就像LOWER(?0) + '%'spring-doc.cadn.net.cn

结束(大小写区分)spring-doc.cadn.net.cn

名字像“%”+ ?0spring-doc.cadn.net.cn

结束(不区分大小写)spring-doc.cadn.net.cn

LOWER(名字)比如“%”+ LOWER(?0)spring-doc.cadn.net.cn

(大小写区分)spring-doc.cadn.net.cn

名字像是'%' + ?0 + '%'spring-doc.cadn.net.cn

(不区分大小写)spring-doc.cadn.net.cn

LOWER(名字)比如“%” + LOWER(?0) + “%”spring-doc.cadn.net.cn

JPA不支持正则表达式匹配。