1.1 Знакомство с HQL
Ранее ты познакомился с Hibernate, а теперь я познакомлю тебя с HQL, он же Hibernate Query Language. Фактически, – это SQL переделанный под написание запросов в Hibernate. У него есть несколько ключевых отличий.
- Использование имени класса вместо имени таблицы.
- Использование имени поля класса вместо имени колонки таблицы.
- Необязательное использование 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.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ