hibernate что такое query как передать в объект query параметры

Язык запросов HQL

HQL (Hibernate Query Language) – это объекто-ориентированный язык запросов, который очень похож на SQL. Главное различие языков HQL и SQL связано с тем, что SQL формирует запросы из наименований таблиц в базе данных и их столбцов, а HQL работает с сущностями (классами) и их полями (аттрибутами класса).

Hibernate транслирует HQL–запросы в понятные для БД SQL–запросы, которые и выполняют необходимые действия в БД.

Рассмотрим основные ключевые операторы языка HQL :

Оператор FROM используется для загрузки (чтения) набора объектов. Пример кода :

User представляет POJO класс (User.java), который ассоциирован с таблицей в БД.

WHERE

Оператор WHERE накладывает условие на выборку определенных записей из БД. В следующем коде оператор WHERE используется точно также, как и в обычном SQL :

Hibernate может использовать оператор WHERE с именованными параметрами (Named Parameters), определяя значение в режиме run-time. Для подстановки соответствующего значения в запрос используется метод setParameter объекта Query, которому в качестве параметров необходимо передать значения :

Запросы HQL не чувствительны к регистру операторов, за исключением названий Java классов и их свойств. Т.е. ‘SeLect’ будет эквивалентен ‘Select’. Но вот с наименованием сущностей/классов и их полями это не проходит; они должны соответствовать описаниям.

INSERT

В коде выполняется попытка сохранения сущности User со значениями login=’oleg’ и name=’Олег’. Структуру таблицы и описание сущности можно увидеть в примере связанных сущностей, который описан здесь. Выполнение данного кода выведет в консоль следующую информацию :

Hibernate сформировал запрос insert и вставил 2 записи. Если посмотреть содержимое таблицы БД, то там можно будет увидеть новые две записи. Полагаю, что вторая запись лишняя, но как от нее избавиться. Если вместо наименования сущности User в первой или во второй позиции подставить наименование таблицы Users, то Hibernate вызовет QuerySyntaxException :

Таким образом, можно заключить, что вставку записей в таблицы при использовании HQL лучше выполнять с применением сущностей и стандартных методов save или saveUpdate объекта сессии, как это представлено в примере.

UPDATE

Ключевое слово UPDATE используется для обновления одного или нескольких полей объекта. При формировании SQL-запроса можно использовать параметры (Named Parameters), рассмотренные выше. Следующий код демонстрирует динамическое определение параметров при обновлении записи. Результат выполнения запроса — количество обновленных (затронутых) записей :

DELETE

Ключевое слово DELETE используется для удаления одного или нескольких объектов из таблицы. Пример использования :

Представленный выше код будет выполнен, если сущность User не имеет связанных объектов, т.е. из таблицы БД будет удалена сущность. Но, если к примеру, User имеет один или несколько связанных объектов Autos, как это представлено в примере связанных сущностей, то сервер БД не сможет удалить запись из таблицы Users, поскольку в таблице Autos имеются «ссылочные» записи. В этом случае Hibernate вызовет org.hibernate.exception.ConstraintViolationException : could not execute statement.

Для удаления связанных сущностей необходимо использовать объект сессии Session. Следующий код демонстрирует удаление пользователя User, у которого имеются связанные объекты (сущности):

В консоль будут выведены следующие сформированные Hibernate запросы удаления сущности User и связанных с ней сущностей Auto :

Обратите внимание, что дочерние/связанные сущности удаляются в первую очередь.

Использование алиаса AS

Оператор AS можно использовать в качестве алиаcа в HQL запросе, особенно, если запрос получается длинным. Следующий код демонстрирует определение алиаса пользователя User как ‘u’ (без его использования в запросе) :

Оператор AS можно не включать в запрос, и сразу же после наименования сущности определить ее алиас :

Ниже представлены примеры кода с использованием алиаса.

GROUP BY

При использовании в HQL агрегатных функций необходимо выполнять группировку по определенным в запросе полям, аналогично SQL. Следующий код демонстрирует использование агрегатной функции SUM с группировкой по полю firstName сущности Employee :

Агрегатные функции HQL

В таблице представлены агрегатные функции, поддерживаемые HQL :

ФункцияОписание
avg (property name)получение среднего значения
count (property name or *)получение количества записей
max (property name)получение максимального значения
min (property name)получение минимального значения
sum (property name)вычисление суммарного значения

Использование оператора DISTINCT позволяет выделить уникальные значения. Следующий запрос вернет количество уникальных имен сотрудников :

ORDER BY

Сортировка результатов запроса в HQL выполняется с использованием ORDER BY аналогично SQL. Сортировать значения можно как по возрастанию (ASC ascending), так и по убыванию (DESC descending). Следующий код демонстрирует чтение сотрудников с сортировкой по убыванию :

Если необходимо выполнить сортировку более чем по одному из полей, то можно после оператора ORDER BY указать список полей с порядком сортировки, разделенных запятой :

Разбиение на страницы

Объект Query включает два метода, позволяющие организовать разбиение данных по-страницам :

Используя вышеописанные методы можно организовать постраничное представление набора данных. Следующий пример выбирает из БД 8 сотрудников, начиная с 5-ой записи :

Источник

Чтение объектов в Hibernate

Извлечение информации из базы данных в виде коллекции объектов Hibernate может выполнять с использованием :

HQLHibernate Query Language;
SQLnative SQL query;
CriteriaHibernate Criteria API.

В данной статье будут рассмотрены различные способы чтения данных без фильтрации и с фильтрацией на основе примера, представленного на странице связанных сущностей, где описаны структуры таблиц базы данных и связанные сущности. Т.е. на этой странице будет продолжено повествование о связанных сущностях с точки зрения их извлечения из БД.

Чтение данных с использованием HQL

Hibernate может использовать свой мощный язык запросов Hibernate Query Language, который очень похож на родной SQL. В сравнении с SQL, HQL полностью объектно-ориентирован и использует понятия наследования, полиформизма и связывания. Подробное описание языка HQL будет представлено в ближайшие дни.

Следующий метод демонстрирует чтение набора данных пользователей User. HQL запрос формируется с использованием наименования класса. После этого создается запрос Query методом createQuery(sql) объекта сессии и извлекаются данные методом list ().

Запросы Hibernate и данные выводятся в консоль (см. ниже). Обратите внимание, что при создании запроса Query методом createQuery(sql) Hibernate формирует соответствующий запрос чтения списка пользователей. Второй запрос по чтению связанных записей Auto формируется и выполняется уже при распечатке пользователя, т.е. при обращении к связанной сущности (lazy загрузка).

Чтение данных с использованием native SQL-запроса

Hibernate позволяет выполнять native SQL-запросы с использованием org.hibernate.SQLQuery, который создается методом createSQLQuery(String) объекта сессии. Но необходимо учитывать, что в этом случае можно потерять все преимущества HQL (ассоциации, кэширование). Следующий код демонстрирует использование нативного запроса для получения коллекции пользователей.

Набор прочитанных данных выводится в консоль, представленную ниже. Обратите внимание, что также, как и для HQL, при использовании native SQL второй запрос чтения связанных сущностей формируется по мере необходимости, т.е. при обращении.

Чтение набора объектов, List

В результате выполнения метода readObjects() в консоль будет выведена информация без подгрузки связанных сущностей Auto :

Использование org.hibernate.Criteria

Интерфейс org.hibernate.Criteria представляет собой объектно-ориентированный запрос на выборку в отношении конкретной сущности и позволяет выполнять запросы без написания SQL кода. Для создания экземпляров Criteria используется класс Session, который выступает в качестве фабрики.

Следующий метод выполняет чтение списка пользователей с именем «Иван». При создании Criteria используется метод createCriteria объекта сессии Session, которому в качестве параметра передается класс объекта. Объект criteria имеет метод add, позволяющий выполнить фильтрацию данных. Для этого методу add необходимо передать параметр ограничения Restrictions с определенными условиями.

Результат выполнения метода readUsers_criteria выведен в консоль :

Подробное описание org.hibernate.Criteria с примерами представлено здесь.

Фильтрация данных в Hibernate

Для чтения данных с фильтрацией можно использовать как org.hibernate.Criteria, представленный выше, так и native SQL. Метод readUsers демонстрирует извлечение отдельной записи пользователя, у которой логин соответствует значению параметра метода «filter» :

При создании объекта SQLQuery (native SQL) была добавлена сущность (addEntity) и определен параметр «log» (setParameter). В консоли увидим следующую информацию :

Чтение отдельной записи

Если известен идентификатор сущности Id, то объект сессии Session позволяет прочитать запись. Для этого можно использовать метод get или load. Отличия методов get и load представлено на странице Hibernate в вопросах и ответах. Следующий код демонстрирует чтение записи пользователя с идентификатором :

Скачать пример

Исходный код рассмотренного на странице примера использования различных способов Hibernate для чтения данных в виде проекта Eclipse, включающий все необходимые библиотеки hibernate, можно скачать здесь (8.02 Mб).

Источник

Глава 11. Работа с объектами

Hibernate — это полное объектно-реляционное решение для отображений, которое не только скрывает от разработчика детали системы управления базами данных, но также предлагает управление состояниями объектов. Это, вместо управления инструкциями SQL на низком уровне, даёт возможность работать с JDBC/SQL на высоком уровне в естественном для Java-приложений объектно-ориентированным стиле.

Другими словами, разработчики приложений Hibernate всегда должны думать о состоянии своих объектов, а не только о выполнении SQL-инструкций.

11.1. Состояния объектов Hibernate

Hibernate определяет и поддерживает следующие состояния объектов:

Рассмотрим более подробно состояния и переход состояний (и методы Hibernate, которые инициируют переход).

11.2. Делаем объекты постоянными (persistent)

Вновь сохданные экземпляры постоянного класса считаются переходными по Hibernate. Мы можем сделать переходный экземпляр постоянным, связав его с сессией:

Обычно вы не беспокоитесь об этой детали, так как обычно используете функцию переходного постоянства (transitive persistence) Hibernate для автоматического сохранения связанных объектов. Тогда даже нарушения ограничений NOT NULL не встретятся — Hibernate позаботится обо всём. Переходное постоянство (Transitive persistence) обсуждается далее в этой главе.

11.3. Загрузка объекта

Методы load() из Session предоставляют способ получения постоянного экземпляра, если вы знаете его идентификатор. load() принимает объект класса и загружает состояние в только что созданный экземпляр этого класса в постоянном состоянии.

Кроме того, вы можете загрузить состояние в данный экземпляр:

Имейте в виду, что load() выдает невосстанавливаемое исключение, если нет соответствующей записи в базе данных. Если класс отображён на прокси, load() просто возвращает неинициализированный прокси и фактически не попадает в базу данных до тех пор, пока вы не вызовете метод прокси. Это полезно, если вы хотите создать связь с объектом, не загружая его из базы данных. Он также позволяет загружать несколько экземпляров в виде пакета, если batch-size определён для отображения классов.

Как много загрузит Hibernate из базы данных и сколько SQL SELECT будут использовано? Это зависит от стратегии выборки (fetching strategy) и объясняется в разделе 20.1 «Стратегии выборки (fetching strategy)».

11.4. Запросы

Если вы не знаете идентификаторы объектов, которые вы ищете, вам нужен запрос. Hibernate поддерживает простой, но мощный объектно-ориентированный язык запросов (HQL). Для создания программных запросов Hibernate поддерживает сложные функциональные возможности: Criteria и Example (QBC и QBE). Вы также можете выразить свой запрос в нативном SQL вашей базы данных, с дополнительной поддержкой Hibernate для преобразования результатов в объекты.

11.4.1. Выполнение запросов

11.4.1.1. Итерирование результатов

11.4.1.2. Запросы, возвращающие кортежи (tuples)

Иногда запросы Hibernate возвращают кортежи объектов. Каждый кортеж возвращается как массив:

11.4.1.3. Скалярные результаты

11.4.1.4. Привязка (bind) параметров

11.4.1.5. Пагинация

Если вам нужно указать границы вашего результирующего набора, то есть максимальное количество записей, которые вы хотите получить, и/или первую запись, которую вы хотите получить, вы можете использовать методы интерфейса Query :

Hibernate знает, как перевести этот ограниченный запрос в нативный SQL вашей СУБД.

11.4.1.6. Прокручиваемая итерация

11.4.1.7. Внешние именованные запросы

Пример 11.1. Определение именованного запроса с помощью @NamedQuery.

Пример 11.2. Определение именованного запроса с помощью

Привязка и выполнение параметров происходит программно, как показано в примере 11.3 «Привязка параметров именованного запроса».

Пример 11.3. Привязка параметров именованного запроса

Фактический программный код не зависит от используемого языка запросов. Вы также можете определить нативные SQL-запросы в метаданных или перенести существующие запросы в Hibernate, поместив их в файлы отображения.

11.4.2. Фильтрация коллекций

Возвращённая коллекция считается сумкой (bag), которая является копией данной коллекции. Оригинальная коллекция не изменяется. Это противоречит импликации имени «filter», но соответствует ожидаемому поведению.

Даже пустой запрос фильтра полезен, например для загрузки подмножества элементов в большой коллекции:

11.4.3. Запросы Criteria

HQL чрезвычайно эффективен, но некоторые разработчики предпочитают строить запросы динамически, используя объектно-ориентированный API. Для этих случаев Hibernate предоставляет интуитивный API запросов Criteria :

API Criteria и связанный с ним Example обсуждаются более подробно в главе 17 «Запросы Criteria».

11.4.4. Запросы на нативном SQL

SQL-запросы могут содержать именованные и позиционные параметры, подобно запросам Hibernate. Более подробную информацию о нативных SQL-запросах в Hibernate можно найти в главе 18. «Нативный SQL».

11.5. Изменение постоянных объектов

Иногда эта модель программирования неэффективна, так как в одной сессии требуется как SQL SELECT для загрузки объекта, так и SQL UPDATE для сохранения его обновлённого состояния. Hibernate предлагает альтернативный подход, используя отсоединённые (detached) экземпляры.

11.6. Изменение отсоединённых (detached) объектов

Многим приложениям необходимо получить объект в одной транзакции, отправить его на уровень пользовательского интерфейса для манипуляций, а затем сохранить изменения в новой транзакции. Приложения, использующие такой подход в среде с высоким уровнем параллельного выполнения, обычно используют данные с версией, чтобы обеспечить изоляцию для «длинной» единицы работы.

Hibernate поддерживает эту модель, обеспечивая повторное присоединение отсоединённых экземпляров с использованием методов Session.update() или Session.merge() :

Приложение должно индивидуально вызывать update() для отсоединённых экземпляров, которые доступны из данного отсоединёного экземпляра, только если оно хочет, чтобы их состояние было обновлено. Это может быть автоматизировано с использованием переходного постоянства (Transitive persistence). Дополнительную информацию см. в разделе 11.11 «Переходное постоянство (Transitive persistence)».

Метод lock() также позволяет приложению повторно ассоциировать объект с новой сессией. Однако отделённый экземпляр должен быть немодифицирован.

11.7. Автоматическое обнаружение состояния

Пользователи Hibernate запросили метод общего назначения, который либо сохраняет переходный экземпляр, генерируя новый идентификатор, либо обновляет/повторно присоединяет отсоединённый экземпляр, связанный с его текущим идентификатором. Метод saveOrUpdate() реализует этот функционал.

Обычно update() или saveOrUpdate() используются в следующем сценарии:

saveOrUpdate() выполняет следующие действия:

а merge() очень отличается:

11.8. Удаление постоянных объектов

Session.delete() удалит состояние объекта из базы данных. Однако ваше приложение может содержать ссылку на удалённый объект. Лучше думать о delete() как о методе, делающем постоянный экземпляр переходным.

Вы можете удалять объекты в любом порядке, без риска нарушения внешнего ключа. По-прежнему можно нарушить ограничение NOT NULL в столбце внешнего ключа, удалив объекты в неправильном порядке. Например, если вы удалите родителя, но забудьте удалить детей.

11.9. Репликация объекта между двумя разными хранилищами данных

Иногда бывает полезно иметь граф постоянных экземпляров и сделать их постоянными в другом хранилище данных, не восстанавливая значения идентификатора.

ReplicationMode определяет, как replicate() будет иметь дело с конфликтами с существующими записями в базе данных:

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

11.10. Сброс (flush) сессии

Иногда Session выполняет инструкции SQL, необходимые для синхронизации состояния соединения JDBC с состоянием объектов, хранящихся в памяти. Этот процесс, называемый сброс (flush), происходит по умолчанию в следующих точках:

Операторы SQL выдаются в следующем порядке:

Исключением является то, что объекты, использующие native генерацию идентификаторов, вставляются при их сохранении.

Во время сброса (flush) может возникнуть исключение (например, если операция DML нарушает ограничение). Поскольку обработка исключений предполагает некоторое понимание поведения транзакционний Hibernate, мы обсуждаем его в главе 13 «Транзакции и параллельное выполнение».

11.11. Переходное постоянство (Transitive persistence)

Довольно обременительно сохранять, удалять или повторно присоединять отсоединённые объекты, особенно если вы имеете дело с графом связанных объектов. Частным случаем является отношение родитель/ребёнок. Рассмотрим следующий пример:

Если детям в отношении родитель/ребёнок будут введены значения (например, набор адресов или строк), их жизненный цикл будет зависеть от родителя, и для удобного «каскадирования» изменений состояния не потребуется никаких дополнительных действий. Когда родитель будет сохранён, дочерние объекты с типом значений (value-typed) сохраняются, а когда родитель будет удалён, дети будут удалены и т.д. Это работает для таких операций, как удаление дочернего объекта из коллекции. Поскольку объекты с типом значений (value-typed) не могут иметь общие ссылки, Hibernate обнаружит это и удалит дочерний объект из базы данных.

Теперь рассмотрим один и тот же сценарий с родительскими и дочерними объектами, являющимися сущностями, а не типами значений (например, категориями и объектами, или родительскими и дочерними кошками). У сущностей есть свой жизненный цикл и поддержка общих ссылок. Удаление сущности из коллекции не означает, что она может быть удалена), и по умолчанию нет каскадирования состояния от одной сущности к любым другим связанным сущностям. Hibernate по умолчанию не реализует постоянство по повторному присоединению.

Каскадные стили можно сочетать:

Если вы используете аннотации, вы, вероятно, заметили, что атрибут cascade принимает массив CascadeType в качестве значения. Каскадная концепция в JPA очень похожа на переходное постоянство (transitive persistence) и каскадирование операций, как описано выше, но с немного отличающейся семантикой и каскадированием типов:

Заметка

Пример 11.4. @OneToMany с orphanRemoval

Отображение ассоциации (либо однозначной ассоциации, либо коллекции) с cascade=«all» помечает ассоциацию как отношение в стиле родитель/ребёнок, где сохранение, обновление или удаление родительского объекта приводит к сохранению, обновлению или удалению дочернего объектов.

Наконец, обратите внимание, что каскадирование операций может быть применено к графу объектов во время вызова или во время сборса. Все операции, если они включены, каскадируются на ассоциированные сущности, доступные при выполнении операции. Однако save-update и delete-orphan являются транзитивными для всех ассоциированных сущностей, доступных во время сессии.

11.12. Использование метаданных

Hibernate требует богатой метауровневой модели всех типов сущностей и значений. Эта модель может быть полезна для самого приложения. Например, приложение может использовать метаданные Hibernate для реализации «умного» алгоритма «глубокого копирования», который понимает, какие объекты следует копировать (например, изменяемые типы значений) и какие нет (например, неизменные типы значений и, возможно, ассоциированные объекты).

Источник

Hibernate — Язык запросов

Hibernate Query Language (HQL) — это объектно-ориентированный язык запросов, похожий на SQL, но вместо работы с таблицами и столбцами HQL работает с постоянными объектами и их свойствами. HQL-запросы преобразуются Hibernate в обычные SQL-запросы, которые, в свою очередь, выполняют действия с базой данных.

Хотя вы можете использовать операторы SQL непосредственно с Hibernate, используя Native SQL, но я бы порекомендовал использовать HQL, когда это возможно, чтобы избежать проблем с переносимостью баз данных и воспользоваться преимуществами стратегий генерации и кэширования SQL в Hibernate.

Ключевые слова, такие как SELECT, FROM, WHERE и т. Д., Не чувствительны к регистру, но такие свойства, как имена таблиц и столбцов, чувствительны к регистру в HQL.

ОТ клаузулы

Если вам нужно полностью указать имя класса в HQL, просто укажите пакет и имя класса следующим образом:

AS пункт

Предложение AS можно использовать для назначения псевдонимов классам в ваших HQL-запросах, особенно если у вас длинные запросы. Например, наш предыдущий простой пример будет следующим:

Ключевое слово AS является необязательным, и вы также можете указать псевдоним непосредственно после имени класса, как показано ниже:

ВЫБРАТЬ пункт

Предложение SELECT обеспечивает больший контроль над результирующим набором, чем предложение from. Если вы хотите получить несколько свойств объектов вместо всего объекта, используйте предложение SELECT. Ниже приведен простой синтаксис использования предложения SELECT для получения только поля first_name объекта Employee.

Следует отметить, что Employee.firstName является свойством объекта Employee, а не полем таблицы EMPLOYEE.

ГДЕ оговорка

Если вы хотите сузить конкретные объекты, которые возвращаются из хранилища, используйте предложение WHERE. Ниже приведен простой синтаксис использования предложения WHERE:

ЗАКАЗАТЬ по пункту

Если вы хотите отсортировать по более чем одному свойству, вы просто добавите дополнительные свойства в конец предложения по предложению, разделенные запятыми следующим образом:

Предложение GROUP BY

Этот пункт позволяет Hibernate извлекать информацию из базы данных и группировать ее по значению атрибута и, как правило, использовать результат для включения совокупного значения. Ниже приведен простой синтаксис использования предложения GROUP BY —

Использование именованных параметров

Hibernate поддерживает именованные параметры в своих HQL-запросах. Это облегчает написание HQL-запросов, которые принимают ввод от пользователя, и вам не нужно защищаться от атак SQL-инъекций. Ниже приведен простой синтаксис использования именованных параметров —

ОБНОВЛЕНИЕ

Массовые обновления являются новыми для HQL с Hibernate 3, и удаляют работу в Hibernate 3 иначе, чем в Hibernate 2. Интерфейс Query теперь содержит метод executeUpdate () для выполнения операторов HQL UPDATE или DELETE.

Предложение UPDATE может использоваться для обновления одного или нескольких свойств одного или нескольких объектов. Ниже приведен простой синтаксис использования предложения UPDATE —

УДАЛИТЬ пункт

Предложение DELETE может использоваться для удаления одного или нескольких объектов. Ниже приведен простой синтаксис использования предложения DELETE:

Вставить пункт

HQL поддерживает предложение INSERT INTO только тогда, когда записи могут быть вставлены из одного объекта в другой. Ниже приведен простой синтаксис использования предложения INSERT INTO:

Агрегатные методы

HQL поддерживает ряд агрегатных методов, похожих на SQL. Они работают так же, как в HQL, так и в SQL, и ниже приведен список доступных функций:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *