JavaRush /Курсы /Модуль 4. Работа с БД /Учимся писать запросы на HQL

Учимся писать запросы на HQL

Модуль 4. Работа с БД
10 уровень , 0 лекция
Открыта

1.1 Знакомство с HQL

Ранее ты познакомился с Hibernate, а теперь я познакомлю тебя с HQL, он же Hibernate Query Language. Фактически, – это SQL переделанный под написание запросов в Hibernate. У него есть несколько ключевых отличий.

  1. Использование имени класса вместо имени таблицы.
  2. Использование имени поля класса вместо имени колонки таблицы.
  3. Необязательное использование select.

Давай попросим Hibernate вернуть нам всех пользователей, которые есть у него в базе. Вот как будет выглядеть этот запрос:


from User
        

Это все, для сравнения приведем аналогичный запрос на SQL:


select * from user
        

Тут User – это имя класса, а user – это имя таблицы.

Полностью Java код будет выглядеть вот так:


public List<User> getAllUsers() {
    try (Session session = sessionFactory.openSession()) {
            return session.createQuery("from User", User.class).list();
    }
}

В остальном HQL очень похож на SQL – в нем тоже есть операторы:

  • WHERE
  • ORDER BY
  • GROUP BY
  • HAVING

1.2 Пример работы с HQL

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

Пусть у нас есть таблица user_data, которая содержит такие поля:

  • id INT
  • user_name VARCHAR(100)
  • user_level INT
  • user_created DATE

Мы создадим Java-класс, который замапим на эту таблицу:


@Entity
@Table(name="user_data")
class User {
   @Id
   @GeneratedValue
   public Integer id;
 
   @Column(name="user_name")
   public String name;
 
   @Column(name="user_level")
   public Integer level;
 
   @Column(name="user_created")
   public Date created;
}

Теперь напишем несколько примеров:

HQL SQL
from User select * from user_data
from User where id=3 select * from user_data where id=3
from User where level in (10,20,30) select * from user_data where user_level IN (10, 20, 30)
from User order by created asc select * from user_data order by user_created asc
from User where name like 'тест' select * from user_data where user_name like 'тест'

Запросы очень похожи, и читать HQL-запросы, когда ты знаком с именами классов и их полей так же легко, как читать SQL-запросы. Писать, возможно, немного сложнее, но опять-таки, на HQL редко пишут очень сложные запросы.

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

В HQL можно использовать select, когда тип данных результата не совпадает с типом указанным в from.

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


select name from User
        

Также если среди имен есть дубликаты, то можно воспользоваться оператором DISTINCT:


select distinct name from User
        

Алиасы работают так же, как и в SQL:


select distinct u.name from User u where u.created > '2020-01-01'

        

Ну и полностью в виде Java-кода этот запрос будет выглядеть вот так:


public List<String> getUserNames() {
    try (Session session = sessionFactory.openSession()) {
            String hql = "select distinct u.name from User u where u.created > '2020-01-01'";
            Query<String> query = session.createQuery(hql , String.class);
            return query.list();
    }
}

Обрати внимание, запрос должен вернуть список имен. Имена имеют тип String, поэтому и тип функции, и тип-параметр класса Query имеют тип String.

1
Задача
Модуль 4. Работа с БД, 10 уровень, 0 лекция
Недоступна
task1001
В методе main получи сессию из MySessionFactory.getSessionFactory(). Напиши запрос на hql для получения колонки smth из таблицы employee...
Комментарии (9)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ольга Николенко Уровень 109 Expert
26 мая 2024
В задаче не предполагается создание транзакции, нужна только сессия и hql, как в примерах в лекции.
Олег Уровень 79 Expert
2 июля 2024
Как я вижу в примерах показаны методы, которые, скорее всего, должны использоваться внутри какого то класса и там, наверное, открывается и закрывается транзакция. Думаю так.... Только в метод должны были бы ещё и передаваться какой то класс(таблица) над которой производится какое то действие, но видно это упростили.....
Kirill Уровень 106 Expert
3 августа 2024
Запрос селект не требует явного создания и закрытия транзакции. Это происходит под капотом автоматически
Алексей Уровень 106 Expert
17 августа 2024
Здесь транзакция в принципе не нужна, мы только получаем данные
Ольга Николенко Уровень 109 Expert
21 сентября 2024
Насколько помню суть сообщения была в том что задание не принимается если создать. Про то что не нужна - понятно, но никто не запрещает ее открывать каждый раз, в реальности транзакции вообще создаются на более высоком уровне, а не на каждый запрос.
Дмитрий Уровень 108 Expert
11 марта 2023
В задачках по гиберу просят подключить библиотеки, для возможности запуска. Я как то прощелкал как саму базу подрубить по задачкам с гибером?
Misha Saharin Уровень 111 Expert
2 мая 2023
если под словом база мы говорим про архив - скачать архив, распаковать на диске. в настройках проекта указать путь к распакованному содержимому архива.
12 мая 2023
В примере так же был вариант с добавлением зависимости в pom.xml
Николай Уровень 109
14 марта 2024
в этой статье описано как подключить БД https://javarush.com/groups/posts/6454-nastroyka-mysql-pod-zadachi-javarush