1. Overview
1.概述
In this tutorial, we’ll continue with the second part of Spring Data Querydsl Web Support. Here, we’ll focus on associated entities and how to create queries over HTTP.
在本教程中,我们将继续进行Spring Data Querydsl Web支持的第二部分。 在这里,我们将关注相关实体以及如何通过HTTP创建查询。
Following the same configuration used in part one, we’ll create a Maven-based project. Please refer to the original article to check how to set up the basics.
按照第一部分使用的配置,我们将创建一个基于Maven的项目。请参考原文,查看如何进行基本设置。
2. Entities
2.实体
First, let’s add a new entity (Address) creating a relationship between the user and her address. We’ve used the OneToOne relationship to keep it simple.
首先,让我们添加一个新的实体(Address),在用户和她的地址之间创建一个关系。我们使用OneToOne关系来保持简单。
Consequently, we’ll have the following classes:
因此,我们将有以下几个班级。
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
private Address addresses;
// getters & setters
}
@Entity
public class Address {
@Id
@GeneratedValue
private Long id;
private String address;
private String country;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
// getters & setters
}
3. Spring Data Repositories
3.Spring数据存储库
At this point, we have to create the Spring Data repositories, as usual, one for each entity. Note that these repositories will have the Querydsl configuration.
在这一点上,我们必须像往常一样创建Spring Data存储库,每个实体一个。注意,这些存储库将有Querydsl配置。
Let’s see the AddressRepository repository and explain how the framework configuration works:
让我们看看AddressRepository存储库,并解释框架配置是如何工作的:。
public interface AddressRepository extends JpaRepository<Address, Long>,
QuerydslPredicateExecutor<Address>, QuerydslBinderCustomizer<QAddress> {
@Override
default void customize(QuerydslBindings bindings, QAddress root) {
bindings.bind(String.class)
.first((SingleValueBinding<StringPath, String>) StringExpression::eq);
}
}
We’re overriding the customize() method to configure the default binding. In this case, we’ll customize the default method binding to be equals, for all String properties.
我们重写customize()方法来配置默认绑定。在这种情况下,我们将自定义默认的方法绑定为等价,用于所有String 属性。
Once the repository is all set, we just have to add a @RestController to manage the HTTP queries.
一旦资源库设置完毕,我们只需要添加一个@RestController来管理HTTP查询。
4. Query Rest Controller
4.查询休息控制器
In part one, we explained the Query@RestController over user repository, here, we’ll just reuse it.
在第一部分中,我们解释了@RestController对userrepository的查询,在这里,我们只是重复使用它。
Also, we may want to query the address table; so for this, we’ll just add a similar method:
另外,我们可能想查询地址表;因此,为此我们将添加一个类似的方法:。
@GetMapping(value = "/addresses", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<Address> queryOverAddress(
@QuerydslPredicate(root = Address.class) Predicate predicate) {
BooleanBuilder builder = new BooleanBuilder();
return addressRepository.findAll(builder.and(predicate));
}
Let’s create some tests to see how this works.
让我们创建一些测试,看看这是如何工作的。
5. Integration Testing
5.集成测试
We’ve included a test to prove how Querydsl works. For this, we are using the MockMvc framework to simulate HTTP querying over user joining this entity with the new one: address. Therefore, we are now able to make queries filtering address attributes.
我们已经包含了一个测试,以证明Querydsl是如何工作的。为此,我们使用MockMvc框架来模拟HTTP查询user与新实体的连接。address。因此,我们现在能够对address 属性进行过滤查询。
Let’s retrieve all users living in Spain:
让我们检索所有居住在西班牙的用户。
/users?addresses.country=Spain
/users?addresses.country=Spain
@Test
public void givenRequest_whenQueryUserFilteringByCountrySpain_thenGetJohn() throws Exception {
mockMvc.perform(get("/users?address.country=Spain")).andExpect(status().isOk()).andExpect(content()
.contentType(contentType))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].name", is("John")))
.andExpect(jsonPath("$[0].address.address", is("Fake Street 1")))
.andExpect(jsonPath("$[0].address.country", is("Spain")));
}
As a result, Querydsl will map the predicate sent over HTTP and generates the following SQL script:
因此,Querydsl将映射通过HTTP发送的谓词,并生成以下SQL脚本。
select user0_.id as id1_1_,
user0_.name as name2_1_
from user user0_
cross join address address1_
where user0_.id=address1_.user_id
and address1_.country='Spain'
6. Conclusion
6.结论
To sum up, we have seen that Querydsl offers to the web clients a very simple alternative to create dynamic queries; another powerful use of this framework.
总而言之,我们已经看到Querydsl为网络客户提供了一个非常简单的替代方案来创建动态查询;这是这个框架的另一个强大用途。
In part I, we saw how to retrieve data from one table; consequently, now, we can add queries joining several tables, offering web-clients a better experience filtering directly over HTTP requests they make.
在第一部分中,我们看到了如何从一个表中检索数据;因此,现在我们可以添加连接多个表的查询,为网络客户提供更好的体验,直接通过他们的HTTP请求进行过滤。
The implementation of this example can be checked in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.