Можно ли выполнять нативные SQL-запросы в Spring Data JPA?

«Можно ли выполнять нативные SQL-запросы в Spring Data JPA?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, Spring Data JPA предоставляет полную поддержку как для JPQL, так и для нативных SQL-запросов.

1. Нативные SQL-запросы: Используйте аннотацию @Query с параметром nativeQuery = true. Идеально для сложных запросов или использования специфичных функций СУБД.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    @Query(
        value = "SELECT * FROM users u WHERE u.registration_date > :date AND u.status = 'ACTIVE'",
        nativeQuery = true
    )
    List<User> findActiveUsersAfterDate(@Param("date") LocalDate date);
}

2. JPQL (Java Persistence Query Language): Объектно-ориентированный язык запросов. Работает с сущностями и их полями, а не с именами таблиц и колонок.

@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
List<User> findByEmailDomain(@Param("domain") String domain);
Ключевые различия и рекомендации: Критерий Нативный SQL JPQL
Переносимость Привязан к конкретной СУБД Независим от СУБД
Безопасность Риск SQL-инъекций при конкатенации строк Защищён параметризацией
Производительность Максимальная (прямой запрос) Может требовать оптимизации
Использование Сложные отчеты, оконные функции, CTE Стандартные операции CRUD с сущностями

⚠️ Важное предупреждение: Всегда используйте именованные параметры (:paramName) или позиционные параметры (?1, ?2) для предотвращения SQL-инъекций. Никогда не конкатенируйте пользовательский ввод в строку запроса.