示例查詢(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<Person> 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<T> {
<S extends T> Optional<S> findOne(Example<S> var1);
<S extends T> Iterable<S> findAll(Example<S> var1);
<S extends T> Iterable<S> findAll(Example<S> var1, Sort var2);
<S extends T> Page<S> findAll(Example<S> var1, Pageable var2);
<S extends T> long count(Example<S> var1);
<S extends T> boolean exists(Example<S> var1);
}
我們可以使用上面接口中定義的方法實現查詢:
messageRepository.findOne(Example.of(user));
示例匹配器
示例匹配器可以用來對字符串的默認匹配方式進行自定義操作,如下所示:
Person person = new Person(); //創建示例
person.setFirstname("Dave"); //設置查詢屬性
ExampleMatcher matcher = ExampleMatcher.matching() //創建一個匹配器
.withIgnorePaths("lastname") //忽略名爲"lastname"的屬性路徑
.withIncludeNullValues() //在上面的條件基礎上 屬性可以爲null(包含空值)
.withStringMatcherEnding(); //執行後綴字符串匹配
Example<Person> 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());
}
Untyped Example
默認情況下,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<Person> result = template.find(query, Person.class);