410013796724260
• Webmoney
R335386147728
Z369087728698
Язык запросов HQLHQL (Hibernate Query Language) – это объекто-ориентированный язык запросов, который очень похож на SQL. Главное различие языков HQL и SQL связано с тем, что SQL формирует запросы из наименований таблиц в базе данных и их столбцов, а HQL работает с сущностями (классами) и их полями (аттрибутами класса). Hibernate транслирует HQL–запросы в понятные для БД SQL–запросы, которые и выполняют необходимые действия в БД. Рассмотрим основные ключевые операторы языка HQL : FROMОператор FROM используется для загрузки (чтения) набора объектов. Пример кода : String hql = "FROM User"; Query query = session.createQuery(hql); List<User> users = query.list(); User представляет POJO класс (User.java), который ассоциирован с таблицей в БД. WHEREОператор WHERE накладывает условие на выборку определенных записей из БД. В следующем коде оператор WHERE используется точно также, как и в обычном SQL : Query query = session.createQuery("FROM User where name = 'Иван'"); List<User> users = query.list(); Hibernate может использовать оператор WHERE с именованными параметрами (Named Parameters), определяя значение в режиме run-time. Для подстановки соответствующего значения в запрос используется метод setParameter объекта Query, которому в качестве параметров необходимо передать значения : String hql = "FROM User where name = :paramName"; Query query = session.createQuery(hql); query.setParameter("paramName", "Alex"); List<User> users = query.list(); Запросы HQL не чувствительны к регистру операторов, за исключением названий Java классов и их свойств. Т.е. 'SeLect' будет эквивалентен 'Select'. Но вот с наименованием сущностей/классов и их полями это не проходит; они должны соответствовать описаниям. INSERTВ HQL поддерживается только форма INSERT INTO ... SELECT ... , которая имеет серьезные ограничения для вставки записей. С точки зрения SQL данная форма позволяет вставить одну или несколько записей в таблицу из запроса SELECT ... . Но это характерно для SQL, а Hibernate (HQL) работает только с сущностями. Попробуем использовать данную форму запроса для вставки записи в Hibernate, и рассмотрим следующий код вставки записи пользователя : String hql = "insert into User (login, name) " + "select 'oleg', 'Олег' from User"; int rows = session.createQuery (hql).executeUpdate(); System.out.println("rows : " + rows); В коде выполняется попытка сохранения сущности User со значениями login='oleg' и name='Олег'. Структуру таблицы и описание сущности можно увидеть в примере связанных сущностей, который описан здесь. Выполнение данного кода выведет в консоль следующую информацию : Hibernate: insert into USERS ( id, login, name ) select SEQ_USER.nextval, 'oleg' as col_0_0_, 'Олег' as col_1_0_ from USERS user0_ rows : 2 Hibernate сформировал запрос insert и вставил 2 записи. Если посмотреть содержимое таблицы БД, то там можно будет увидеть новые две записи. Полагаю, что вторая запись лишняя, но как от нее избавиться. Если вместо наименования сущности User в первой или во второй позиции подставить наименование таблицы Users, то Hibernate вызовет QuerySyntaxException : Exception in thread "main" \ org.hibernate.hql.internal.ast.QuerySyntaxException: \ Users is not mapped [ \ insert into Users(login, name) \ select 'oleg', 'Олег' from net.common.model.User] Таким образом, можно заключить, что вставку записей в таблицы при использовании HQL лучше выполнять с применением сущностей и стандартных методов save или saveUpdate объекта сессии, как это представлено в примере. UPDATEКлючевое слово UPDATE используется для обновления одного или нескольких полей объекта. При формировании SQL-запроса можно использовать параметры (Named Parameters), рассмотренные выше. Следующий код демонстрирует динамическое определение параметров при обновлении записи. Результат выполнения запроса — количество обновленных (затронутых) записей : String hql = "update Contact " + "SET firstName = :name " + ", lastName = :lastName " + ", date = :dateParam " + " where id = :idParam" Query query = session.createQuery(hql); query.setParameter("idParam" , 48); query.setParameter("name" , "Киса"); query.setParameter("lastName" , "Воробьянинов"); query.setParameter("dateParam", new Date()); int result = query.executeUpdate(); DELETEКлючевое слово DELETE используется для удаления одного или нескольких объектов из таблицы. Пример использования : String hql = "DELETE User WHERE login = :lg"; Query query = session.createQuery(hql); query.setParameter("lg", "oleg"); int rows = query.executeUpdate(); Представленный выше код будет выполнен, если сущность User не имеет связанных объектов, т.е. из таблицы БД будет удалена сущность. Но, если к примеру, User имеет один или несколько связанных объектов Autos, как это представлено в примере связанных сущностей, то сервер БД не сможет удалить запись из таблицы Users, поскольку в таблице Autos имеются «ссылочные» записи. В этом случае Hibernate вызовет org.hibernate.exception.ConstraintViolationException : could not execute statement. Для удаления связанных сущностей необходимо использовать объект сессии Session. Следующий код демонстрирует удаление пользователя User, у которого имеются связанные объекты (сущности): User user = session.load(User.class, 50); if (user != null) { session.delete(user); } В консоль будут выведены следующие сформированные Hibernate запросы удаления сущности User и связанных с ней сущностей Auto : Hibernate: delete from autos where aid=? Hibernate: delete from autos where aid=? Hibernate: delete from USERS where id=? Обратите внимание, что дочерние/связанные сущности удаляются в первую очередь. Использование алиаса ASОператор AS можно использовать в качестве алиаcа в HQL запросе, особенно, если запрос получается длинным. Следующий код демонстрирует определение алиаса пользователя User как 'u' (без его использования в запросе) : String hql = "FROM User AS u"; Query query = session.createQuery(hql); List results = query.list(); Оператор AS можно не включать в запрос, и сразу же после наименования сущности определить ее алиас : String hql = "FROM User u"; Query query = session.createQuery(hql); List results = query.list(); Ниже представлены примеры кода с использованием алиаса. GROUP BYПри использовании в HQL агрегатных функций необходимо выполнять группировку по определенным в запросе полям, аналогично SQL. Следующий код демонстрирует использование агрегатной функции SUM с группировкой по полю firstName сущности Employee : String hql = "SELECT SUM (e.salary), e.firtName " + "FROM Employee e " + "GROUP BY e.firstName"; Query query = session.createQuery(hql); List results = query.list(); Агрегатные функции HQLВ таблице представлены агрегатные функции, поддерживаемые HQL :
Использование оператора DISTINCT позволяет выделить уникальные значения. Следующий запрос вернет количество уникальных имен сотрудников : String hql = "SELECT COUNT (distinct e.firstName) " + "FROM Employee e"; Query query = session.createQuery(hql); List results = query.list(); ORDER BYСортировка результатов запроса в HQL выполняется с использованием ORDER BY аналогично SQL. Сортировать значения можно как по возрастанию (ASC ascending), так и по убыванию (DESC descending). Следующий код демонстрирует чтение сотрудников с сортировкой по убыванию : String hql = "FROM Employee e " + "WHERE e.id > 10 ORDER BY e.salary DESC"; Query query = session.createQuery(hql); List results = query.list(); Если необходимо выполнить сортировку более чем по одному из полей, то можно после оператора ORDER BY указать список полей с порядком сортировки, разделенных запятой : String hql = "FROM Employee e " + "WHERE e.id > 10 " + "ORDER BY e.firstName DESC, e.salary DESC"; Query query = session.createQuery(hql); List results = query.list(); Разбиение на страницыОбъект Query включает два метода, позволяющие организовать разбиение данных по-страницам :
Используя вышеописанные методы можно организовать постраничное представление набора данных. Следующий пример выбирает из БД 8 сотрудников, начиная с 5-ой записи : String hql = "FROM Employee"; Query query = session.createQuery(hql); query.setFirstResult(5); query.setMaxResults (8); List results = query.list(); |