Querydsl Web Support 實現 Rest 查詢

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

需要解釋幾點:

  1. 重載QuerydslBinderCustomizer 的customize() 方法覆蓋默認綁定
  2. 修改默認的equals比較。所有字符串類型屬性忽略大小寫模糊匹配。
  3. 排查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進行條件查詢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章