Hibernate — примеры Criteria. Обзор Hibernate Criteria API
Hibernate — примеры установки критериев (ограничений) Criteria. Сравнение с HQL
Hibernate Criteria API является альтернативным подходом к Hibernate Query Language (HQL). Этот подход более объектно-ориентирован и позволяет сократить необходимый код. Может быть рекомендован в проектах с большим количеством запросов с критериями.
Используемые технологии:
Hibernate 5.0.1.Final
Maven 3.2.5
IntelliJ IDEA 14
MySQL 5.6.25
1. Описание задачи
Рассмотреть основы Hibernate Criteria и сравнить код с аналогом на HQL.
Будем делать следующую выборку — из таблицы с контактами вытаскиваем только те значения, у которых дата младше (новее) чем год назад.
2. Структура проекта
Используется база данных и классы из Hibernate – быстрый старт. Пример приложения Hello World. Там же есть исходники. Рекомендую прочитать эту статью, чтобы было понятно что и откуда берется_вставляется. Для наглядности приведу пример данных и таблицу, используемую в этой статье:
3. Пример кода HQL
Рассмотрим вначале как выглядит код выборки из базы данных с установленными ограничениями в стиле HQL (примеры HQL: select, insert, delete, update).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
private static List getNameHQL(Calendar startDate, Calendar endDate, Session session) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); boolean isFirst = true; StringBuilder query = new StringBuilder("from ContactEntity "); if(startDate != null) { if (isFirst) { query.append(" where birth_date >= '" + simpleDateFormat.format(startDate.getTime()) + "'"); } else { query.append(" and birth_date >= '" + simpleDateFormat.format(startDate.getTime()) + "'"); } isFirst = false; } if(endDate != null) { if (isFirst) { query.append(" where birth_date <= '" + simpleDateFormat.format(endDate.getTime()) + "'"); } else { query.append(" and birth_date <= '" + simpleDateFormat.format(endDate.getTime()) + "'"); } isFirst = false; } query.append(" order by birth_date"); Query result = session.createQuery(query.toString()); return result.list(); } |
Создаем запрос, который звучит как: вытащить все данные из ContactEntity где дата соответствует промежутку startDate — endDate и отсортировать результат по дате.
4. Пример с использованием Criteria
Приведу распространенный, но уже устаревший вариант создания ограничений:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private static List getNameCriteria(Calendar startDate, Calendar endDate, Session session) { Criteria criteria = session.createCriteria(ContactEntity.class); if(startDate != null) { criteria.add(Restrictions.ge("birthDate", startDate.getTime())); /*@DEPRECATED criteria.add(Expression.ge("birth_date", startDate.getTime())); */ } if(endDate != null) { criteria.add(Restrictions.le("birthDate", endDate.getTime())); } criteria.addOrder(Order.asc("birthDate")); return criteria.list(); } |
Смысл и результат такие же как в предыдущем пункте.
Важно
Обратите внимание, что Expression — уже @Deprecated. Но, что более важно в версии Hibernate, которая используется в этой статье и Restrictions тоже уходит в прошлое. Jboss.org указывает, что org.hibernate.Criteria API должно считаться устаревшим, а вместо этого необходимо использовать спецификацию JPA и javax.persistence.criteria.CriteriaQuery. JPA будет описываться в отдельной статье.
Criteria API
Простой запрос Criteria
Создать объект criteria и возвратить все записи ContactEntity из базы данных
1 |
Criteria criteria = session.createCriteria(ContactEntity.class); |
Сортировка в запросе Criteria
Отсортировать результаты по возрастанию firstName:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .addOrder(Order.asc("firstName"); |
Отсортировать результаты по убыванию firstName:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .addOrder(Order.desc("firstName"); |
Запросы с ограничениями Criteria
Restrictions. eq; lt; le; gt; ge
Значение value равно 400:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.eq("value", 400); |
Значение value меньше 400:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.lt("value", 400); |
Значение value меньше или равно 400:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.le("value", 400); |
Значение value больше 400:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.gt("value", 400); |
Значение value больше или равно 400:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.ge("value", 400); |
Restriction.like
Значение firstName начинается с Name и дальше любые символы:
1 2 |
Criteria criteria = session.createCriteria(someClass.class) .add(Restrictions.like("firstName", "Name%"); |
Restriction.between
Значение birth_date находится между датами:
1 2 |
Criteria criteria = session.createCriteria(ContactEntity.class) .add(Restrictions.between("birth_date", startDate, endDate); |
Restriction.isNull, isNotNull
Значение birth_date — null:
1 2 |
Criteria criteria = session.createCriteria(ContactEntity.class) .add(Restrictions.isNull("birth_date"); |
Значение birth_date — не null:
1 2 |
Criteria criteria = session.createCriteria(ContactEntity.class) .add(Restrictions.isNotNull("birth_date"); |
Разделение результатов запроса Criteria
Начать с 20 записи и возвратить 15 следующих записей из базы данных:
1 2 3 |
Criteria criteria = session.createCriteria(ContactEntity.class); criteria.setMaxResults(15); criteria.setFirstResult(20); |
Использовать или нет Criteria?
Как уже было сказано в замечании выше — в таком виде как в этой статье, нежелательно. Необходимо использовать стандарт JPA. Тем не менее кода, использующего этот подход очень много и он еще долго будет поддерживаться.
Также следует учесть, что вы не имеете никакого контроля над запросом, генерируемым Hibernate. Соответственно если важна производительность, то возможно следует рассмотреть другой подход.
Ещё одним минусом является сам текст запроса — в случае ошибки будет сложно отлавливать какой из запросов написан неверно. В случае именованных запросов всё будет замапино на объекты Java и увидеть исключение гораздо проще.
Вывод: использовать или нет Criteria нужно принимать исходя из потребностей проекта.
Ссылки для скачивания
hibernateCriteria — sql дамп для MySQL вместе с таблицами и данными
Hibernate Criteria — проект в IntelliJ IDEA
12One thought on “Hibernate — примеры Criteria. Обзор Hibernate Criteria API”
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
С нетерпением жду)) У вас рассылка на почту приходит о новых статьях?