示例查询(QBE)是一种简单的用户友好查询技术,它可以动态构建查询体,并且不需要开发者便携包含字段名称的查询
按示例查询分为三个组件:
-- Probe:可以理解为为查询构建的实例对象
-- ExampleMatcher:
-- Example:由Probe和ExampleMathcer组成,用于创建查询
使用示例查询的一些限制:
-- 不支持嵌套或者分组
-- 不支持字符串的开始、包含、结束和正则表达式匹配
实例1 简单的查询示例
1.创建一个Probe(对象)
@Data
public class Person{
@Id
private String id;
private String firstname;
private String lastname;
private Address address;
}
使用@Data添加get、set方法,这个对象将本用来构建一个Example,默认情况下,属性值为null时将会被忽略,并且字符串类型的数据将会被特定的默认值匹配
of():工厂方法,用来构建示例
Example是固定不变的,下面是一个简答的使用示例
2.简单示例
Person person = new Person(); //构建一个新的实例
person.setFirstname("Dave"); //设置查询属性
Example example = Example.of(person); //创建示例
3. 执行查询
这里我们要用到一个mongoDB存储库的扩展接口,具体源码如下:
package org.springframework.data.repository.query;
import java.util.Optional;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
public interface QueryByExampleExecutor {
Optional findOne(Example var1);
Iterable findAll(Example var1);
Iterable findAll(Example var1, Sort var2);
Page findAll(Example var1, Pageable var2);
long count(Example var1);
boolean exists(Example var1);
}
我们可以使用上面接口中定义的方法实现查询:
messageRepository.findOne(Example.of(user));
示例匹配器可以用来对字符串的默认匹配方式进行自定义操作,如下所示:
Person person = new Person(); //创建示例
person.setFirstname("Dave"); //设置查询属性
ExampleMatcher matcher = ExampleMatcher.matching() //创建一个匹配器
.withIgnorePaths("lastname") //忽略名为"lastname"的属性路径
.withIncludeNullValues() //在上面的条件基础上 属性可以为null(包含空值)
.withStringMatcherEnding(); //执行后缀字符串匹配
Example example = Example.of(person, matcher); // 创建一个包含匹配器的示例
默认情况下:ExampleMatcher期望实例上设置的所有字段都匹配
配置匹配器选项
可以为单个属性设置一些特有的处理方式
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("firstname", endsWith())
.withMatcher("lastname", startsWith().ignoreCase());
}
使用lamdas配置匹配器选项 (java8以上版本可用)
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("firstname", match -> match.endsWith())
.withMatcher("firstname", match -> match.startsWith());
}
默认情况下,Example是严格输入,这意味着映射出来的查询中的属性是包含类型的情况下匹配的,也就是说,在进行匹配器匹配的时候,是带着属性的值;类型进行匹配的
untypedExampleMatcher是可以绕过默认匹配行为并且跳过类型限制,值匹配字段名称,如下
class JustAnArbitraryClassWithMatchingFieldName {
@Field("lastname") String value;
}
JustAnArbitraryClassWithMatchingFieldNames probe = new JustAnArbitraryClassWithMatchingFieldNames();
probe.value = "stark";
Example example = Example.of(probe, UntypedExampleMatcher.matching());
Query query = new Query(new Criteria().alike(example));
List result = template.find(query, Person.class);