Querydsl Web Support 實現 Rest 查詢
本文我們討論Spring Data Querydsl Web Support,非常有趣的web查詢功能實現方案。
maven 依賴
首先增加maven依賴:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
從spring-data-commons 1.11版本開始支持Querydsl web support 功能。
定義Repository
首先定義示例UserRepository:
JpaRepository<User, Long>, QueryDslPredicateExecutor<User>, QuerydslBinderCustomizer<QUser> {
@Override
default public void customize(QuerydslBindings bindings, QUser root) {
bindings.bind(String.class).first(
(StringPath path, String value) -> path.containsIgnoreCase(value));
bindings.excluding(root.email);
}
}
需要解釋幾點:
- 重載QuerydslBinderCustomizer 的customize() 方法覆蓋默認綁定
- 修改默認的equals比較。所有字符串類型屬性忽略大小寫模糊匹配。
- 排查email字段作爲查詢條件
定義Controller
下面開始定義controller:
@RequestMapping(method = RequestMethod.GET, value = "/users")
@ResponseBody
public Iterable<User> findAllByWebQuerydsl( @QuerydslPredicate(root = User.class) Predicate predicate) {
return userRepository.findAll(predicate);
}
這是最有趣的部分,注意我們是如何從HttpRequest中直接獲得Predicate,是通過@QuerydslPredicate註解。
下面url是實現這種類型的查詢:
http://localhost:8080/users?firstName=john
響應結果類似這樣:
[
{
"id":1,
"firstName":"john",
"lastName":"doe",
"email":"[email protected]",
"age":11
}
]
實際測試
最後,我們進行真實場景測試:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class UserLiveTest {
private ObjectMapper mapper = new ObjectMapper();
private User userJohn = new User("john", "doe", "[email protected]");
private User userTom = new User("tom", "doe", "[email protected]");
private static boolean setupDataCreated = false;
@Before
public void setupData() throws JsonProcessingException {
if (!setupDataCreated) {
givenAuth().contentType(MediaType.APPLICATION_JSON_VALUE)
.body(mapper.writeValueAsString(userJohn))
.post("http://localhost:8080/users");
givenAuth().contentType(MediaType.APPLICATION_JSON_VALUE)
.body(mapper.writeValueAsString(userTom))
.post("http://localhost:8080/users");
setupDataCreated = true;
}
}
private RequestSpecification givenAuth() {
return RestAssured.given().auth().preemptive().basic("user1", "user1Pass");
}
}
首先,獲取系統中所有用戶:
@Test
public void whenGettingListOfUsers_thenCorrect() {
Response response = givenAuth().get("http://localhost:8080/users");
User[] result = response.as(User[].class);
assertEquals(result.length, 2);
}
接着,根據last name 查詢用戶:
@Test
public void givenPartialLastName_whenGettingListOfUsers_thenCorrect() {
Response response = givenAuth().get("http://localhost:8080/users?lastName=do");
User[] result = response.as(User[].class);
assertEquals(result.length, 2);
}
最後,嘗試根據email進行查詢:
@Test
public void givenEmail_whenGettingListOfUsers_thenIgnored() {
Response response = givenAuth().get("http://localhost:8080/users?email=john");
User[] result = response.as(User[].class);
assertEquals(result.length, 2);
}
注意:當根據email進行查詢時,條件被忽略,因爲我們在Predicate中排除了email條件。
總結
本文快速通過示例展示了非常酷的Spring Data Querydsl Web Support 功能。可以非常簡單地從HttpRequest中獲取Predicate進行條件查詢。