6.6. Query by Example 利用Example查询

6.6.1. Introduction
This chapter provides an introduction to Query by Example and explains how to use it.
Query by Example (QBE) is a user-friendly querying technique with a simple interface. It allows dynamic query creation and does not require you to write queries that contain field names. In fact, Query by Example does not require you to write queries by using store-specific query languages at all.
6.6.1.介绍
这个章节介绍了,怎么利用Example进行查询
利用Example查询(QBE)是一种通过简单接口实现用户友好查询的技术。他允许动态查询条件不需要指定字段名称。事实上,利用Example查询一点都不需要编写特定的查询语句

6.6.2. Usage
The Query by Example API consists of three parts:
Probe: The actual example of a domain object with populated fields.
ExampleMatcher: The ExampleMatcher carries details on how to match particular fields. It can be reused across multiple Examples.
Example: An Example consists of the probe and the ExampleMatcher. It is used to create the query.
Query by Example is well suited for several use cases:
Querying your data store with a set of static or dynamic constraints.
Frequent refactoring of the domain objects without worrying about breaking existing queries.
Working independently from the underlying data store API.
Query by Example also has several limitations:
No support for nested or grouped property constraints, such as firstname = ?0 or (firstname = ?1 and lastname = ?2).
Only supports starts/contains/ends/regex matching for strings and exact matching for other property types.
Before getting started with Query by Example, you need to have a domain object. To get started, create an interface for your repository, as shown in the following example

6.6.2. 用法
利用Example查询接口包含三个部分:
Probe: 带有指定字段的domain对象(类似java bean)
ExampleMatcher:ExampleMatcher落实指定字段匹配规则,而且他可以被多个Example重用
Example:Example由Probe和ExampleMatcher组成,他用来创建查询
利用Example查询比较适合下面的场景:
利用一组静态或动态的约束条件进行查询数据
经常重构domain对象,而不用担心破坏现有的查询
与底层数据存储API是松耦合的
利用Example也有一些限制:
不支持嵌套或分组约束,比如firstname = ?0 or (firstname = ?1 and lastname = ?2)
仅支持string类型的starts/contains/ends/regex 匹配规则,对其他类型仅精确匹配
在开始利用Example查询,首先需要一个domain对象、repository接口,就像下面这样的例子
Example 100. Sample Person object

public class Person {
     @Id
      private String id;
      private String firstname;
      private String lastname;
      private Address address;
     // … getters and setters omitted
}
The preceding example shows a simple domain object. You can use it to create an Example. By default, fields having null values are ignored, and strings are matched by using the store specific defaults.
  *Inclusion of properties into a Query by Example criteria is based on nullability. Properties using primitive types (int, double, …) are always included unless ignoring the property path.

上面的例子展示了一个简单的domain对象,可以利用它创建Example.默认情况,null值的字段会被忽略,string类型通过默认值进行匹配
  *利用Example查询条件,通常基于可为空的属性。如果是基本类型(int、double...)也是被包含的,除非另有说明忽略特定属性

Examples can be built by either using the of factory method or by using ExampleMatcher. Example is immutable. The following listing shows a simple Example:

Example可以通过工厂方法或者通过ExampleMatcher创建。Example是不可变的。下面展示了一个简单的Example
Example 101. Simple Example
          Person person = new Person();  //创建一个domain对象实例
          person.setFirstname("Dave");    // 设置查询属性
          Example<Person> example = Example.of(person);  // 创建Example

You can run the example queries by using repositories. To do so, let your repository interface extend QueryByExampleExecutor<T>. The following listing shows an excerpt from the QueryByExampleExecutor interface:
你可以利用repository执行查询,为了达到这个目的,先让接口继承 QueryByExampleExecutor<T>。下面展示了QueryByExampleExecutor 接口的摘要
Example 102. The 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.
}

6.6.3. Example Matchers
Examples are not limited to default settings. You can specify your own defaults for string matching, null handling, and property-specific settings by using the ExampleMatcher, as shown in the following example:
Example对默认设置没有限制。对string你可以指定自己的默认匹配规则,空处理,特定属性设置,就像下面的例子
Example 103. Example matcher with customized matching


       

Person person = new Person();    // a、创建一个domain对象实例
person.setFirstname("Dave");    // b、设置属性
ExampleMatcher matcher = ExampleMatcher.matching() .// c、创建一个ExampleMatcher,即使没有进一步配置也是可用的
withIgnorePaths("lastname") .  // d、构造一个新的ExampleMatcher忽略lastname属性
withIncludeNullValues() .     //e、构造一个新的ExampleMatcher忽略lastname属性且包含空值
withStringMatcherEnding();   //f、构造一个新的ExampleMatcher忽略lastname属性且包含空值、且以后缀匹配
Example<Person> example = Example.of(person, matcher);  // g、利用domain 和 ExampleMatcher 构造一个Examaple

By default, the ExampleMatcher expects all values set on the probe to match. If you want to get results matching any of the predicates defined implicitly, use ExampleMatcher.matchingAny().
默认ExampleMatcher 是精确匹配查询的,如果想要模糊查询可以使用ExampleMatcher.matchingAny()
You can specify behavior for individual properties (such as "firstname" and "lastname" or, for nested properties, "address.city"). You can tune it with matching options and case sensitivity, as shown in the following example:
你可以指定单个属性的行为(比如,firstName和lastName,或者嵌套属性,address.city),可以用他们调节匹配条件或者大小写,就像下面的例子
Example 104. Configuring matcher options

ExampleMatcher matcher = ExampleMatcher.matching()
            .withMatcher("firstname", endsWith())
           .withMatcher("lastname", startsWith().ignoreCase());

Queries created by Example use a merged view of the configuration. Default matching settings can be set at the ExampleMatcher level, while individual settings can be applied to particular property paths. Settings that are set on ExampleMatcher are inherited by property path settings unless they are defined explicitly. Settings on a property patch have higher precedence than default settings. The following table describes the scope of the various ExampleMatcher settings:

利用Example创建的查询,是利用一个配置的合并视图。在ExampleMatcher有默认的设置,同时当有对于特殊的字段可以有个性的设置。设置是可以被继承的除非被明确指定不可继承.在属性的设置优先级比默认设置优先级更高。下面的表展示了ExampleMatcher的各种设置

Table 4. Scope of  ExampleMatcher settings
SettingScope

Null-handling

ExampleMatcher

String matching

ExampleMatcher and property path

Ignoring properties

Property path

Case sensitivity

ExampleMatcher and property path

Value transformation

Property path

6.6.4. Running an Example

In Spring Data JPA, you can use Query by Example with Repositories, as shown in the following example:

在Spring Data JPA,你可以利用Example的接口进行查询,下面是展示的例子

Example 106. Query by Example using a Repository

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));
  }
}

The property specifier accepts property names (such as firstname and lastname). You can navigate by chaining properties together with dots (address.city). You can also tune it with matching options and case sensitivity.

属性说明符访问的属性名称(比如firstName和lastName),也可以利用链式属性(比如address.city).可以设置匹配项设置和大小写是否敏感

The following table shows the various StringMatcher options that you can use and the result of using them on a field named firstname:

下面的表展示了StringMatcher的可以使用的设置。利用firstName做举例

Table 5.  StringMatcher options
MatchingLogical result

DEFAULT (case-sensitive)

firstname = ?0

DEFAULT (case-insensitive)

LOWER(firstname) = LOWER(?0)

EXACT (case-sensitive)

firstname = ?0

EXACT (case-insensitive)

LOWER(firstname) = LOWER(?0)

STARTING (case-sensitive)

firstname like ?0 + '%'

STARTING (case-insensitive)

LOWER(firstname) like LOWER(?0) + '%'

ENDING (case-sensitive)

firstname like '%' + ?0

ENDING (case-insensitive)

LOWER(firstname) like '%' + LOWER(?0)

CONTAINING (case-sensitive)

firstname like '%' + ?0 + '%'

CONTAINING (case-insensitive)

LOWER(firstname) like '%' + LOWER(?0) + '%'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值