Преобразование результатов GROUP BY в Spring Data JPA
Быстрый ответ
Для того чтобы преобразовать результаты группировки в пользовательский объект передачи данных (DTO) при помощи Spring Data JPA, используйте конструкцию new внутри определения JPQL-запроса через аннотацию @Query:
public class Summary {
private String category;
private Long count;
public Summary(String category, Long count) {
this.category = category;
this.count = count;
}
// Геттеры и сеттеры...
}
public interface Repo extends JpaRepository<Entity, Long> {
@Query("SELECT new package.path.to.Summary(e.category, COUNT(e)) FROM Entity e GROUP BY e.category")
List<Summary> groupByCategory();
}
Пожалуйста, убедитесь, что вы создали DTO Summary с необходимым конструктором и полями, которые вы собираетесь использовать в @Query для получения сгруппированных данных.

Создание DTO и исполнение интерфейса
Процесс создания пользовательского объекта невероятно прост
Для начала важно грамотно сформулировать класс DTO. Удостоверьтесь, что у него есть конструктор и поля, соответствующие столбцам в вашем запросе.
Ключевое слово 'new' в JPQL — ваша магическая палочка
При формировании JPQL-запросов несомненно необходимо использовать слово new. Оно позволяет сгенерировать экземпляр вашего DTO прямо в процессе выполнения запроса.
Вызов интерфейса в контексте нативных запросов
При выполнении нативных запросов используйте проекции на основе интерфейсов для гарантированного получения данных из сущностей.
Сопоставление результатов — из пункта А в пункт Б
Когда вы получили List<Object[]>, вам нужно преобразовать его в список DTO, с учетом порядка и типов данных конструктора.
Осмотрительное отношение к пустым значениям
Выполняйте проверку на null, чтобы предотвратить возникновение проблем при обработке результатов.
Lombok и статические ссылки — путь к сокращению кода и облегчению поддержки проекта
Сократите объем кода, используя Lombok, и упростите свою работу при поддержке проекта, добавив в ваш код статические ссылки на имена свойств.
Визуализация
Предположим, что каждый товар в вашей корзине – это объект DTO:
🛒 Ваша корзина (DTO):
- Яблоки (`GROUP BY` тип) 🍏: 5
- Апельсины (`GROUP BY` тип) 🍊: 3
- Бананы (`GROUP BY` тип) 🍌: 2
Сбор корзины схож с выполнением запроса с использованием GROUP BY:
@Query("SELECT new com.example.ShoppingBasket(COUNT(*), Type) FROM Fruit GROUP BY Type")
List<ShoppingBasket> countFruitsByType();
Результат: красиво организованная корзина с фруктами, сгруппированными по типу.
Внедрение знаний на практических примерах
Заботьтесь о последовательности и типах в DTO
Следите за тем, чтобы последовательность и типы полей DTO соответствовали вашему JPQL-запросу.
Репозиторий — идеальное место для порядка
Пользуйтесь аннотацией @Query на уровне репозитория, чтобы воспользоваться функционалом Spring Data для формирования сложных запросов.
'new map' в JPQL — ключ к динамическим результатам запроса
С помощью ключевого слова new map в JPQL вы сможете динамически формировать результаты запроса.
Особенности работы со сложными связями и агрегированием
При работе со сложными агрегациями и связями заранее подготовьте запросы, которые соответствуют задуманной структуре данных.
Упрощение использования с Lombok
Метод @Getter из библиотеки Lombok поможет вам избавиться от необходимости написания рутинного кода.
Отдаём предпочтение DTO вместо HashMap
Выберите DTO вместо HashMap для большей типизированности и лучше структурированного кода.
Полезные материалы
- Spring Data JPA — официальная документация, где объясняется использование аннотации
@Query. - JPQL SELECT clause — разберитесь, как создавать объекты при помощи JPA-запросов.
- JPQL — всё о
GROUP BYи других особенностях JPQL. - Spring Data JPA проекции на основе интерфейсов — подробное руководство по созданию проекций в Spring Data JPA.
- Spring Data JPA предисловие — введение в документацию Spring Data JPA.
- Java Persistence/JPQL — детальное руководство по языку запросов Java Persistence.


