Querydsl Web Support 实现 Rest 查询

Querydsl Web Support 实现 Rest 查询

本文我们讨论Spring Data Querydsl Web Support,非常有趣的web查询功能实现方案。

maven 依赖

首先增加maven依赖:

    org.springframework.boot
    spring-boot-starter-parent
    1.3.0.RELEASE

 

    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.springframework.data
        spring-data-commons
    
    
        com.mysema.querydsl
        querydsl-apt
        ${querydsl.version}
    
    
        com.mysema.querydsl
        querydsl-jpa
        ${querydsl.version}
    

从spring-data-commons 1.11版本开始支持Querydsl web support 功能。

定义Repository

首先定义示例UserRepository:

  JpaRepository, QueryDslPredicateExecutor, QuerydslBinderCustomizer {
    @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 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进行条件查询。

你可能感兴趣的:(spring,data)