ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Подсчет результатов CriteriaQuery в JPA 2 без извлечения

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Используйте CriteriaBuilder и EntityManager для проведения базового подсчёта результатов:

Java
Скопировать код
// Создаём CriteriaBuilder
CriteriaBuilder cb = em.getCriteriaBuilder();
// Готовим запрос на подсчёт
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
// Определяем корневой элемент запроса
Root<MyEntity> entityRoot = countQuery.from(MyEntity.class);
// Устанавливаем критерий для подсчёта
countQuery.select(cb.count(entityRoot));

// Выполняем запрос и получаем результат
Long total = em.createQuery(countQuery).getSingleResult();

Замените MyEntity наименованием вашего класса сущности, а cb.count(entityRoot) используйте для подсчёта количества записей.

Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Изящный подсчёт: Distinct, Joins и немного Повторного использования

Подсчёт уникальных сущностей

Для подсчёта уникальных значений используйте выражение countDistinct:

Java
Скопировать код
// Создаём запрос на подсчёт уникальных значений атрибута
CriteriaQuery<Long> countDistinctQuery = cb.createQuery(Long.class);
Root<MyEntity> root = countDistinctQuery.from(MyEntity.class);
countDistinctQuery.select(cb.countDistinct(root.get("distinctAttr")));

// Получаем количество уникальных записей
Long countDistinct = em.createQuery(countDistinctQuery).getSingleResult();

Оптимизация соединений

Проводите эффективный подсчёт, используя операцию join:

Java
Скопировать код
// Инициализируем запрос на подсчёт с применением join
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
Root<MyEntity> root = countQuery.from(MyEntity.class);
// Производим соединение связанных сущностей
Join<MyEntity, RelatedEntity> joinedTable = root.join("relatedEntity", JoinType.LEFT);
countQuery.select(cb.count(root)).where(cb.equal(joinedTable.get("attribute"), "conditionValue"));

// Получаем результат подсчёта
Long countWithJoin = em.createQuery(countQuery).getSingleResult();

Паттерн повторного использования критериев

Применяйте методы повторного использования для устранения дублирования кода:

Java
Скопировать код
// Метод для ведения общего подсчёта по классу сущности
public Long getCountForClass(EntityManager em, Class<MyEntity> domainClass) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Long> cq = cb.createQuery(Long.class);
    cq.select(cb.count(cq.from(domainClass)));
    return em.createQuery(cq).getSingleResult();
}

Визуализация

Используйте аналогии: если вам нужно подсчитать количество пассажиров, зачем просматривать каждый вагон?

Markdown
Скопировать код
CriteriaQuery<Train>.select(TrainStation).where(Condition).getResultList();

Применяйте следующий код для подсчёта:

Java
Скопировать код
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
countQuery.select(cb.count(countQuery.from(Train.class)));
entityManager.createQuery(countQuery).getSingleResult(); // Ваш билет на подсчёт

Приведённый пример наглядно демонстрирует эффективность подсчёта за один запрос.

Справление со сложными подсчётами

В сложных ситуациях помните о различиях между JPA провайдерами и потенциальных проблемах с производительностью при использовании join-операций.

Оптимизация подсчётов

Избегайте использования fetch joins для оптимизации подсчётов, чтобы не нарастить нагрузку на систему.

Гении повторного использования

Реализуйте универсальные классы для генерации запросов подсчёта, передавая EntityManager и класс сущности в конструктор.

Тонкости работы с провайдерами

Присмотритесь к особенностям разных реализаций JPA, адаптируя запросы подсчёта в соответствии с их спецификациями.

Полезные материалы

  1. CriteriaBuilder (Java(TM) EE 7 Specification APIs) — Основы работы с методом CriteriaBuilder.count в JPA.
  2. JPA Criteria API Queries — Вводный материал по работе с Criteria API в JPA.
  3. Java persistence API – Tutorial — Справочник по JPA и Criteria API.
  4. Java Persistence/Criteria – Wikibooks — Ресурс для изучения Java Persistence Criteria.
  5. Using the Criteria API to Create Queries — Детальное руководство по Criteria API.
  6. Обсуждение на Stack Overflow о подсчёте в CriteriaQuery — Форум для обмена опытом о подсчёте в CriteriaQuery.