Язык запросов REST для нескольких таблиц с поддержкой Querydsl Web

1. Обзор

В этом руководстве мы продолжим вторую часть ссылки:/rest-api-search-querydsl-web-in-spring-data-jpa Здесь мы сосредоточимся о связанных объектах и ​​о том, как создавать запросы по HTTP.

Следуя той же конфигурации, которая использовалась в первой части, мы создадим проект на основе Maven. Пожалуйста, обратитесь к оригинальной статье, чтобы проверить, как настроить основы.

2. Сущности

  • Во-первых, давайте добавим новую сущность ( _Address) _ , создающую отношение между пользователем и его адресом. ** Мы использовали отношение OneToOne, чтобы упростить его.

Следовательно, у нас будут следующие классы:

@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
}

[[Spring Data Repositories]]

3. Хранилища данных Spring

На данный момент мы должны создать репозитории Spring Data, как обычно, по одному для каждой сущности. Обратите внимание, что эти репозитории будут иметь конфигурацию Querydsl.

  • Давайте посмотрим репозиторий 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);
    }
}

Мы переопределяем метод customize () для настройки привязки по умолчанию. В этом случае мы настроим привязку метода по умолчанию равной для всех свойств _String _

Как только репозиторий будет полностью настроен, нам просто нужно добавить @ RestController для управления HTTP-запросами

4. Query Rest Controller

В первой части мы объяснили Query _ @ RestController over user _ репозиторий, здесь мы просто будем использовать его повторно.

  • Также мы можем запросить таблицу address ; поэтому для этого мы просто добавим похожий метод: **

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

Давайте создадим несколько тестов, чтобы увидеть, как это работает.

5. Интеграционное тестирование

Мы включили тест, чтобы доказать, как работает Querydsl. Для этого мы используем инфраструктуру MockMvc для имитации HTTP-запросов через user , соединяя эту сущность с новой: address. Таким образом, теперь мы можем создавать запросы, фильтрующие адрес__ атрибутов.

  • Давайте вернем всех пользователей, живущих в Испании: **

/users? address.country = Испания

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

В результате 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. Заключение

Подводя итог, мы видели, что Querydsl предлагает веб-клиентам очень простую альтернативу для создания динамических запросов; другое мощное использование этой структуры.

В ссылке:/rest-api-search-querydsl-web-in-spring-data-jpa[часть I]мы увидели, как извлечь данные из одной таблицы; следовательно, теперь мы можем добавлять запросы, соединяющие несколько таблиц, предлагая веб-клиентам более удобную фильтрацию непосредственно по HTTP-запросам, которые они делают.

Реализацию этого примера можно проверить in в проекте GitHub - это проект на основе Maven, поэтому он должен быть легко импортировать и запускать как есть.