Java query insert into

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

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

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

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

FROM

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

String hql = "FROM User"; Query query = session.createQuery(hql); List users = query.list();

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

WHERE

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

Query query = session.createQuery("FROM User where name = 'Иван'"); List 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 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 объекта сессии, как это представлено в примере.

Читайте также:  Прекращена работа программы windows html

UPDATE

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

String hql = "update Contact " + "SET firstName = :name " + ", lastName = :lastName " + ", date = :dateParam " + " where 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)

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

Hibernate: delete from autos where aid=? Hibernate: delete from autos where aid=? Hibernate: delete from USERS where >Обратите внимание, что дочерние/связанные сущности удаляются в первую очередь.

Использование алиаса 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();

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

Читайте также:  Python telegram bot mail

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 :

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

Использование оператора 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 включает два метода, позволяющие организовать разбиение данных по-страницам :

  • setFirstResult (int start) — параметр start определяет первую извлекаемую запись в запросе (отсчет от 0);
  • setMaxResults (int max) — параметр max определяет количество извлекаемых записей в результирующем запросе.

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

String hql = "FROM Employee"; Query query = session.createQuery(hql); query.setFirstResult(5); query.setMaxResults (8); List results = query.list();

Источник

Читайте также:  Json parse localstorage typescript

Вставка данных в таблицу

Мы разобрались, как создавать таблицы, давай теперь детально рассмотрим, как добавлять данные в таблицу с помощью SQL-запроса.

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

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

Общий вид запроса вставки данных в таблицу выглядит так:

INSERT INTO таблица (колонка1, колонка2, колонка3) VALUES (значение1, значение2, значение3), (значение1, значение2, значение3), (значение1, значение2, значение3); 

Например, ты хочешь вставить в таблицу user новую запись, вот как будет выглядеть такой запрос:

INSERT INTO user (name, level, created_time) VALUES (‘Рабинович’, 5, ‘2022-06-06’); 

Оператор INSERT INTO SELECT

Еще один частый сценарий вставки данных в таблицу — это взять их из другой таблицы, схемы и даже СУБД.

Для этого есть другой формат запроса INSERT INTO, у которого вместо части VALUES можно указать запрос на выборку данных.

Общий вид такого запроса имеет вид:

INSERT INTO таблица (колонка1, колонка2, колонка3) SELECT-запрос; 

Давай напишем запрос, с помощью которого добавим всех пользователей из таблицы employee в таблицу user:

INSERT INTO user (name, created_time) SELECT employee.name, employee.join_date FROM employee; 

У нас в таблице employee есть различные данные, но из них мы выбираем только два поля – имя и время прихода в компанию.

Так же таблица user требует указать ей уровень пользователя – level. В таблице employee у сотрудников нет уровня, поэтому мы воспользуемся тем, что у таблицы user у поля level есть значение по умолчанию. Мы просто не будем указывать level, и SQL установит значение по умолчанию.

Допустим, нас не устраивает значение по умолчанию, и мы хотим, чтобы level был 99, а user.created_time заменить на сегодняшнюю дату, тогда можно написать так:

INSERT INTO user (name, level, created_time) SELECT employee.name, 99, CURDATE() FROM employee; 

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

Источник

Оцените статью