«1. Обзор

В этой статье показаны различные способы использования JPA для сортировки.

2. Сортировка с помощью JPA/JQL API

Использование JQL для сортировки выполняется с помощью предложения Order By:

String jql ="Select f from Foo as f order by f.id";
Query query = entityManager.createQuery (jql);

На основе этого запроса JPA генерирует следующий простой оператор SQL: ~~ ~

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ 
    from Foo foo0_ order by foo0_.id

Обратите внимание, что ключевые слова SQL в строке JQL не чувствительны к регистру, в отличие от имен сущностей и их атрибутов.

2.1. Установка порядка сортировки

По умолчанию порядок сортировки восходящий, но его можно явно задать в строке JQL. Так же, как и в чистом SQL, варианты упорядочения — asc и desc:

String jql = "Select f from Foo as f order by f.id desc";
Query sortQuery = entityManager.createQuery(jql);

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

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ 
    from Foo foo0_ order by foo0_.id desc

2.2. Сортировка по более чем одному атрибуту

Для сортировки по нескольким атрибутам они добавляются в предложение order by строки JQL:

String jql ="Select f from Foo as f order by f.name asc, f.id desc";
Query sortQuery = entityManager.createQuery(jql);

Оба условия сортировки появятся в сгенерированном операторе SQL-запроса:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ 
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc

~ ~~ 2.3. Установка приоритета сортировки нулевых значений

Приоритет нулевых значений по умолчанию зависит от базы данных, но его можно настроить с помощью предложения NULLS FIRST или NULLS LAST в строке запроса HQL.

Вот простой пример — упорядочивание по имени Foo в порядке убывания и размещение нулей в конце: строка):

Query sortQuery = entityManager.createQuery
    ("Select f from Foo as f order by f.name desc NULLS LAST");

2.4. Сортировка отношений «один ко многим»

Hibernate: select foo0_.id as id1_4_, foo0_.BAR_ID as BAR_ID2_4_, 
    foo0_.bar_Id as bar_Id2_4_, foo0_.name as name3_4_,from Foo foo0_ order 
    by case when foo0_.name is null then 1 else 0 end, foo0_.name desc

Оставив основные примеры, давайте теперь рассмотрим вариант использования, включающий сортировку сущностей в отношении «один ко многим» — Bar, содержащий набор сущностей Foo.

Мы хотим отсортировать объекты Bar, а также их коллекцию объектов Foo — JPA особенно прост для этой задачи:

Обратите внимание, что аннотация @OrderBy является необязательной, но мы используем ее в этом случае, потому что мы хотите отсортировать коллекцию Foo каждого бара.

  1. Sorting the Collection: Add an OrderBy annotation preceding the Foo collection in the Bar entity:
    @OrderBy("name ASC")
    List <Foo> fooList;
  2. Sorting the entity containing the collection:
    String jql = "Select b from Bar as b order by b.id";
    Query barQuery = entityManager.createQuery(jql);
    List<Bar> barList = barQuery.getResultList();

Давайте посмотрим на SQL-запрос, отправленный в RDMS:

Первый запрос сортирует родительский объект Bar. Второй запрос генерируется для сортировки коллекции дочерних сущностей Foo, принадлежащих Bar.

Hibernate: select bar0_.id as id1_0_, bar0_.name as name2_0_ from Bar bar0_ order by bar0_.id

Hibernate: 
select foolist0_.BAR_ID as BAR_ID2_0_0_, foolist0_.id as id1_4_0_, 
foolist0_.id as id1_4_1_, foolist0_.BAR_ID as BAR_ID2_4_1_, 
foolist0_.bar_Id as bar_Id2_4_1_, foolist0_.name as name3_4_1_ 
from Foo foolist0_ 
where foolist0_.BAR_ID=? order by foolist0_.name asc

3. Сортировка с помощью JPA Criteria Query Object API

С помощью JPA Criteria — метод orderBy является универсальной альтернативой для установки всех параметров сортировки: можно указать как направление порядка, так и атрибуты для сортировки. набор. Ниже приведен API метода:

orderBy(CriteriaBuilder.asc): Сортировка в порядке возрастания. orderBy(CriteriaBuilder.desc): сортирует по убыванию.

    Каждый экземпляр Order создается с помощью объекта CriteriaBuilder с помощью его методов asc или desc.

Вот краткий пример — сортировка Foos по имени:

Аргумент метода get чувствителен к регистру, поскольку он должен соответствовать имени атрибута.

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")));

В отличие от простого JQL, JPA Criteria Query Object API задает явное направление порядка в запросе. Обратите внимание, что в последней строке этого фрагмента кода объект критерияBuilder указывает порядок сортировки по возрастанию, вызывая его метод asc.

Когда приведенный выше код выполняется, JPA генерирует SQL-запрос, показанный ниже. Объект JPA Criteria генерирует оператор SQL с явным предложением asc:

3.1. Сортировка по более чем одному атрибуту

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc

Для сортировки по более чем одному атрибуту просто передайте экземпляр Order методу orderBy для каждого атрибута для сортировки.

Вот краткий пример — сортировка по имени и идентификатору в порядке возрастания и убывания соответственно:

Соответствующий SQL-запрос показан ниже:

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class); 
CriteriaQuery<Foo> select = criteriaQuery.select(from); 
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")),
    criteriaBuilder.desc(from.get("id")));

4. Заключение ~~ ~ В этой статье рассматриваются альтернативы сортировки в Java Persistence API для простых сущностей, а также для сущностей в отношении «один ко многим». Эти подходы делегируют бремя работы по сортировке на уровень базы данных.

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ 
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc

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

«

The implementation of this JPA Sorting Tutorial can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.