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 ListfindOrderedBySeatNumberLimitedTo(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();
Если мы ограничимся одним результатом экземпляра, как указано выше, то мы также можем обернуть результат с помощью Необязательно :
OptionalfindFirstByOrderBySeatNumberAsc(); Optional findTopByOrderBySeatNumberAsc();
5.2. Просмотр страниц
В качестве альтернативы мы можем использовать объект Pageable :
Pagepage = repository.findAll( PageRequest.of(0, 1, Sort.by(Sort.Direction.ASC, "seatNumber")));
Если мы посмотрим на реализацию по умолчанию JpaRepository, SimpleJpaRepository , мы увидим, что она также вызывает Query#setMaxResults :
protectedPage < 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 .