← Назад к вопросам

Что такое Query в Hibernate?

2.0 Middle🔥 121 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Query в Hibernate: Интерфейс для выполнения запросов

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

Основные типы Query

1. Query (HQL - Hibernate Query Language)

HQL — это объектно-ориентированный язык запросов Hibernate (похож на SQL, но работает с объектами):

Session session = sessionFactory.openSession();
Query<User> query = session.createQuery(
    "FROM User WHERE age > :age",
    User.class
);
query.setParameter("age", 18);
List<User> users = query.list();
session.close();

2. NativeQuery (Native SQL)

Для выполнения обычного SQL:

Session session = sessionFactory.openSession();
NativeQuery<User> query = session.createNativeQuery(
    "SELECT * FROM users WHERE age > :age",
    User.class
);
query.setParameter("age", 18);
List<User> users = query.list();
session.close();

Основные методы Query

1. setParameter - установка параметров

Query<User> query = session.createQuery(
    "FROM User WHERE age > :age AND name = :name",
    User.class
);
query.setParameter("age", 18);
query.setParameter("name", "John");

2. list() - получить все результаты

Query<User> query = session.createQuery(
    "FROM User ORDER BY name",
    User.class
);
List<User> allUsers = query.list();

3. uniqueResult() - получить один результат

Query<User> query = session.createQuery(
    "FROM User WHERE id = :id",
    User.class
);
query.setParameter("id", 1L);
User user = query.uniqueResult();

4. setMaxResults / setFirstResult - пагинация

Query<User> query = session.createQuery(
    "FROM User ORDER BY name",
    User.class
);
int pageSize = 10;
int offset = 0;
query.setFirstResult(offset);
query.setMaxResults(pageSize);
List<User> page = query.list();

5. executeUpdate() - обновление/удаление

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery(
    "UPDATE User SET age = :newAge WHERE age < :oldAge"
);
query.setParameter("newAge", 18);
query.setParameter("oldAge", 18);
int updatedCount = query.executeUpdate();
tx.commit();
session.close();

HQL примеры

Простой SELECT

Query<User> query = session.createQuery(
    "FROM User u WHERE u.age > 18",
    User.class
);
List<User> adults = query.list();

Проекция (выбор конкретных полей)

Query<String> query = session.createQuery(
    "SELECT u.name FROM User u",
    String.class
);
List<String> names = query.list();

Агрегирующие функции

Query<Long> countQuery = session.createQuery(
    "SELECT COUNT(u) FROM User u",
    Long.class
);
Long total = countQuery.uniqueResult();

Query<Double> avgQuery = session.createQuery(
    "SELECT AVG(u.age) FROM User u",
    Double.class
);
Double avgAge = avgQuery.uniqueResult();

JOIN запросы

Query<Object[]> query = session.createQuery(
    "SELECT u, p FROM User u INNER JOIN u.posts p",
    Object[].class
);
List<Object[]> results = query.list();

Практический пример

@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
    private String name;
    private int age;
}

@Repository
public class UserRepository {
    private final SessionFactory sessionFactory;
    
    public List<User> findAdults() {
        Session session = sessionFactory.openSession();
        Query<User> query = session.createQuery(
            "FROM User WHERE age >= 18 ORDER BY name",
            User.class
        );
        List<User> users = query.list();
        session.close();
        return users;
    }
    
    public List<User> findByNameContains(String namePattern) {
        Session session = sessionFactory.openSession();
        Query<User> query = session.createQuery(
            "FROM User WHERE LOWER(name) LIKE LOWER(:pattern)",
            User.class
        );
        query.setParameter("pattern", "%" + namePattern + "%");
        List<User> users = query.list();
        session.close();
        return users;
    }
    
    public List<User> findPaginated(int pageSize, int pageNumber) {
        Session session = sessionFactory.openSession();
        Query<User> query = session.createQuery(
            "FROM User ORDER BY id",
            User.class
        );
        int offset = (pageNumber - 1) * pageSize;
        query.setFirstResult(offset);
        query.setMaxResults(pageSize);
        List<User> users = query.list();
        session.close();
        return users;
    }
}

Native SQL пример

@Repository
public class UserNativeRepository {
    private final SessionFactory sessionFactory;
    
    public List<User> findUsersWithComplexLogic() {
        Session session = sessionFactory.openSession();
        NativeQuery<User> query = session.createNativeQuery(
            "SELECT u.* FROM users u WHERE u.age > (SELECT AVG(age) FROM users) ORDER BY u.age DESC",
            User.class
        );
        List<User> users = query.list();
        session.close();
        return users;
    }
}

Кэширование Query

@Repository
public class CachedUserRepository {
    private final SessionFactory sessionFactory;
    
    public User findById(Long id) {
        Session session = sessionFactory.openSession();
        Query<User> query = session.createQuery(
            "FROM User WHERE id = :id",
            User.class
        );
        query.setParameter("id", id);
        query.setCacheable(true);
        query.setCacheRegion("user.findById");
        User user = query.uniqueResult();
        session.close();
        return user;
    }
}

Предотвращение SQL-инъекций

Query<User> query = session.createQuery(
    "FROM User WHERE name = :name",
    User.class
);
query.setParameter("name", userInput);
List<User> users = query.list();

Spring Data JPA (современный подход)

public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findAll();
    Optional<User> findById(Long id);
    List<User> findByAgeGreaterThan(int age);
    List<User> findByNameContainingIgnoreCase(String name);
    
    @Query("SELECT u FROM User u WHERE u.age > :age ORDER BY u.name")
    List<User> findAdults(@Param("age") int age);
    
    @Query(value = "SELECT * FROM users WHERE age > ?", nativeQuery = true)
    List<User> findAdultsNative(int age);
}

Лучшие практики

  1. Всегда используйте параметры (setParameter) для предотвращения SQL-инъекций
  2. Используйте HQL вместо Native SQL когда возможно
  3. Закрывайте Session после использования
  4. Используйте пагинацию для больших результатов
  5. Кэшируйте часто используемые запросы
  6. Предпочитайте Spring Data JPA для новых проектов
  7. Профилируйте N+1 проблемы — частая причина низкой производительности

Query в Hibernate — это мощный инструмент для взаимодействия с БД, обеспечивающий безопасность, производительность и читаемость кода.