Рубрики
Без рубрики

Ограничение результатов запросов с помощью JPA и Spring Data JPA

Узнайте об ограничении результатов запросов с помощью JPA и Spring Data JPA.

Автор оригинала: baeldung.

1. введение

В этом уроке мы собираемся узнать об ограничении результатов запросов с помощью JPA и Spring Data JPA .

Во-первых, мы рассмотрим таблицу, которую мы хотим запросить, а также SQL-запрос, который мы хотим воспроизвести.

Затем мы сразу же погрузимся в то, как достичь этого с помощью JPA и Spring Data JPA.

Давайте начнем!

2. Данные Испытаний

Ниже у нас есть таблица, которую мы будем запрашивать на протяжении всей этой статьи.

Вопрос, на который мы хотим ответить, звучит так: “Какое первое занятое место и кто его занимает?”.

Кузнец Джилл 50
Джексон Канун 94
Блоги Фред 22
Бобби Рики 36
Колиси Сия 85

3. SQL

С помощью SQL мы могли бы написать запрос, который выглядит примерно так:

SELECT firstName, lastName, seatNumber FROM passengers ORDER BY seatNumber LIMIT 1;

4. Настройка JPA

С JPA нам сначала нужна сущность, чтобы сопоставить нашу таблицу:

@Entity
class Passenger {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    private Long id;

    @Basic(optional = false)
    @Column(nullable = false)
    private String fistName;

    @Basic(optional = false)
    @Column(nullable = false)
    private String lastName;

    @Basic(optional = false)
    @Column(nullable = false)
    private int seatNumber;

    // constructor, getters etc.
}

Далее нам нужен метод, который инкапсулирует наш код запроса, реализованный здесь как Passenger RepositoryImpl#findOrderedBySeatNumberLimitedTo(int limit) :

@Repository
class PassengerRepositoryImpl {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List findOrderedBySeatNumberLimitedTo(int limit) {
        return entityManager.createQuery("SELECT p FROM Passenger p ORDER BY p.seatNumber",
          Passenger.class).setMaxResults(limit).getResultList();
    }
}

В нашем методе репозитория мы используем EntityManager для создания Запроса , для которого мы вызываем метод setMaxResults () .

Этот вызов Query#setMaxResults в конечном итоге приведет к тому, что оператор limit будет добавлен к сгенерированному SQL:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number limit ?

5. С пружинными данными JPA

Мы также можем генерировать наш SQL с помощью Spring Data JPA.

5.1. первый или верхний

Один из способов, которым мы могли бы подойти к этому, – это использование деривации имени метода с ключевыми словами first или top.

При необходимости мы можем указать число в качестве максимального размера результата, который будет возвращен. Если мы опустим его, Spring Data JPA примет размер результата 1.

Помня, что мы хотим знать, какое первое занятое место и кто его занимает, мы можем получить его, опустив число этими двумя способами:

Passenger findFirstByOrderBySeatNumberAsc();
Passenger findTopByOrderBySeatNumberAsc();

Если мы ограничимся одним результатом экземпляра, как указано выше, то мы также можем обернуть результат с помощью Необязательно :

Optional findFirstByOrderBySeatNumberAsc();
Optional findTopByOrderBySeatNumberAsc();

5.2. Просмотр страниц

В качестве альтернативы мы можем использовать объект Pageable :

Page page = repository.findAll(
  PageRequest.of(0, 1, Sort.by(Sort.Direction.ASC, "seatNumber")));

Если мы посмотрим на реализацию по умолчанию JpaRepository, SimpleJpaRepository , мы увидим, что она также вызывает Query#setMaxResults :

protected  Page < S > readPage(TypedQuery < S > query, 
  Class < S > domainClass, Pageable pageable,
  @Nullable Specification < S > spec) {
    if (pageable.isPaged()) {
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
    }

    return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> {
        return executeCountQuery(this.getCountQuery(spec, domainClass));
    });
}

5.3. Сравнение

Обе эти альтернативы создадут SQL, который нам нужен:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_ 
from passenger passenger0_ order by passenger0_.seat_number asc limit ?

С первым и верхним благоприятствующим соглашением и доступной для просмотра страниц благоприятствующей конфигурацией.

6. Заключение

Ограничение результатов запроса в JPA немного отличается от SQL – мы не включаем ключевое слово limit непосредственно в наш JPQL .

Вместо этого мы просто делаем один вызов метода Query#maxResults или включаем ключевое слово first или top в наше имя метода Spring Data JPA .

Как всегда, вы можете найти код на GitHub .