Criteria API

Criteria API
Criteria API – способ формировать запросы не в виде строки, а с помощью Java-объектов и методов. Относится к JPA 2.0+ (Hibernate также поддерживает).
Основные классы: CriteriaBuilder – фабрика для построения запросов (получается от EntityManager), CriteriaQuery<T> – сам настраиваемый запрос (обобщен типом результата), Root<Ent> – корневой "источник" данных в запросе (например, Root<User> userRoot = query.from(User.class)).
Поддерживает все возможности SELECT-запросов: проекции (выбор полей), фильтрацию (Predicate для WHERE), сортировку (orderBy), группировку, агрегаты и соединения (root.join("orders") даст JOIN с сущностью, связанной через поле orders).
Плюсы: полная типобезопасность – вместо названий полей в строке используются метamodel или поля класса, что проверяется компилятором. Запрос можно динамически собирать условия (например, если параметр метода не null – добавить доп. предикат). Недостаток – более объемный и сложный для чтения код по сравнению с HQL/SQL строкой.
Пример (поиск пользователей по шаблону):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);
Predicate cond = cb.like(user.get("name"), "%Ivan%");
query.select(user).where(cond).orderBy(cb.asc(user.get("age")));
List<User> result = em.createQuery(query).getResultList();
Здесь мы программно сформировали: SELECT u FROM User u WHERE u.name LIKE '%Ivan%' ORDER BY u.age ASC.



Пояснение

 Criteria API часто используют, когда:
Нужно построить запрос по множеству параметров, которые могут присутствовать или отсутствовать. Например, фильтр в интернет-магазине: может быть указан диапазон цены, категория, наличие на складе – и под каждое условие не хочется писать отдельный метод с JPQL. Тогда программист составляет Criteria-запрос: начинает с query = cb.createQuery(Product.class); root = query.from(Product.class); criteriaList = new ArrayList<>(); и затем if (minPrice != null) criteriaList.add(cb.ge(root.get("price"), minPrice)); и т.д., а в конце query.where(criteriaList.toArray(new Predicate[0]));. Это гибко и вписывается в обычный Java-код.
Кодогенераторы и IDE могут помогать с Criteria, к тому же есть концепция Metamodel: для каждой сущности можно сгенерировать класс с статическими метами полей. Тогда вместо user.get("name") строкой пишется User_.name – это поле, сгенерированное метамоделью, типа SingularAttribute<User, String>. Это еще более безопасно, потому что при rename поля IDE изменит и здесь, и вы избежите опечатки.
Несмотря на громоздкость, Criteria гарантирует, что вы не получите ошибок в runtime из-за опечатки в названии поля или несоответствия типа – все строится методами.
В чистом Hibernate (до JPA 2.0) был собственный API Criteria, сейчас в режиме JPA все используют CriteriaBuilder. Если запрос очень сложный, и Criteria становится слишком сложным, обычно это признак, что логика выбора может быть вынесена в представление (SQL) или что проще написать кусок JPQL или нативного SQL.
Автор: к.п.н., Румянцев Сергей Александрович, доцент Финансового университета при Правительстве РФ; доцент ОЧУВО Международного инновационного университета; Консалтинг, управление разработкой ПО; системный и бизнес анализ; менеджмент; аналитиз данных; управление ИТ. Телефон для связи +79269444818 (мессенджеры)   Короткая ссылка:
Criteria API
Criteria API – способ формировать запросы не в виде строки, а с помощью Java-объектов и методов. Относится к JPA 2.0+ (Hibernate также поддерживает).
Основные классы: CriteriaBuilder – фабрика для построения запросов (получается от EntityManager), CriteriaQuery<T> – сам настраиваемый запрос (обобщен типом результата), Root<Ent> – корневой "источник" данных в запросе (например, Root<User> userRoot = query.from(User.class)).
Поддерживает все возможности SELECT-запросов: проекции (выбор полей), фильтрацию (Predicate для WHERE), сортировку (orderBy), группировку, агрегаты и соединения (root.join("orders") даст JOIN с сущностью, связанной через поле orders).
Плюсы: полная типобезопасность – вместо названий полей в строке используются метamodel или поля класса, что проверяется компилятором. Запрос можно динамически собирать условия (например, если параметр метода не null – добавить доп. предикат). Недостаток – более объемный и сложный для чтения код по сравнению с HQL/SQL строкой.
Пример (поиск пользователей по шаблону):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);
Predicate cond = cb.like(user.get("name"), "%Ivan%");
query.select(user).where(cond).orderBy(cb.asc(user.get("age")));
List<User> result = em.createQuery(query).getResultList();
Здесь мы программно сформировали: SELECT u FROM User u WHERE u.name LIKE '%Ivan%' ORDER BY u.age ASC.



Пояснение

 Criteria API часто используют, когда:
Нужно построить запрос по множеству параметров, которые могут присутствовать или отсутствовать. Например, фильтр в интернет-магазине: может быть указан диапазон цены, категория, наличие на складе – и под каждое условие не хочется писать отдельный метод с JPQL. Тогда программист составляет Criteria-запрос: начинает с query = cb.createQuery(Product.class); root = query.from(Product.class); criteriaList = new ArrayList<>(); и затем if (minPrice != null) criteriaList.add(cb.ge(root.get("price"), minPrice)); и т.д., а в конце query.where(criteriaList.toArray(new Predicate[0]));. Это гибко и вписывается в обычный Java-код.
Кодогенераторы и IDE могут помогать с Criteria, к тому же есть концепция Metamodel: для каждой сущности можно сгенерировать класс с статическими метами полей. Тогда вместо user.get("name") строкой пишется User_.name – это поле, сгенерированное метамоделью, типа SingularAttribute<User, String>. Это еще более безопасно, потому что при rename поля IDE изменит и здесь, и вы избежите опечатки.
Несмотря на громоздкость, Criteria гарантирует, что вы не получите ошибок в runtime из-за опечатки в названии поля или несоответствия типа – все строится методами.
В чистом Hibernate (до JPA 2.0) был собственный API Criteria, сейчас в режиме JPA все используют CriteriaBuilder. Если запрос очень сложный, и Criteria становится слишком сложным, обычно это признак, что логика выбора может быть вынесена в представление (SQL) или что проще написать кусок JPQL или нативного SQL.
https://webprogr.ru/~x2bpE
Короткая ссылка на новость:https://webprogr.ru/~x2bpE


Последние новости

Criteria API

Criteria API
Criteria API – способ формировать запросы не в виде строки, а с помощью Java-объектов и методов. Относится к JPA 2.0+ (Hibernate также поддерживает).
Основные классы: CriteriaBuilder – фабрика для построения запросов (получается от EntityManager), CriteriaQuery<T> – сам настраиваемый запрос (обобщен типом результата), Root<Ent> – корневой "источник" данных в запросе (например, Root<User> userRoot = query.from(User.class)).
Поддерживает все возможности SELECT-запросов: проекции (выбор полей), фильтрацию (Predicate для WHERE), сортировку (orderBy), группировку, агрегаты и соединения (root.join("orders") даст JOIN с сущностью, связанной через поле orders).
Плюсы: полная типобезопасность – вместо названий полей в строке используются метamodel или поля класса, что проверяется компилятором. Запрос можно динамически собирать условия (например, если параметр метода не null – добавить доп. предикат). Недостаток – более объемный и сложный для чтения код по сравнению с HQL/SQL строкой.
Пример (поиск пользователей по шаблону):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);
Predicate cond = cb.like(user.get("name"), "%Ivan%");
query.select(user).where(cond).orderBy(cb.asc(user.get("age")));
List<User> result = em.createQuery(query).getResultList();
Здесь мы программно сформировали: SELECT u FROM User u WHERE u.name LIKE '%Ivan%' ORDER BY u.age ASC.



Пояснение

 Criteria API часто используют, когда:
Нужно построить запрос по множеству параметров, которые могут присутствовать или отсутствовать. Например, фильтр в интернет-магазине: может быть указан диапазон цены, категория, наличие на складе – и под каждое условие не хочется писать отдельный метод с JPQL. Тогда программист составляет Criteria-запрос: начинает с query = cb.createQuery(Product.class); root = query.from(Product.class); criteriaList = new ArrayList<>(); и затем if (minPrice != null) criteriaList.add(cb.ge(root.get("price"), minPrice)); и т.д., а в конце query.where(criteriaList.toArray(new Predicate[0]));. Это гибко и вписывается в обычный Java-код.
Кодогенераторы и IDE могут помогать с Criteria, к тому же есть концепция Metamodel: для каждой сущности можно сгенерировать класс с статическими метами полей. Тогда вместо user.get("name") строкой пишется User_.name – это поле, сгенерированное метамоделью, типа SingularAttribute<User, String>. Это еще более безопасно, потому что при rename поля IDE изменит и здесь, и вы избежите опечатки.
Несмотря на громоздкость, Criteria гарантирует, что вы не получите ошибок в runtime из-за опечатки в названии поля или несоответствия типа – все строится методами.
В чистом Hibernate (до JPA 2.0) был собственный API Criteria, сейчас в режиме JPA все используют CriteriaBuilder. Если запрос очень сложный, и Criteria становится слишком сложным, обычно это признак, что логика выбора может быть вынесена в представление (SQL) или что проще написать кусок JPQL или нативного SQL.
Рейтинг@Mail.ru