Ответ
Нативные запросы в JPA — это SQL-запросы, написанные на диалекте конкретной СУБД, которые выполняются напрямую, минуя механизмы преобразования JPQL/HQL. Они предоставляют полный контроль над синтаксисом запроса.
Когда использовать нативные запросы:
- Для сложных
JOIN-операций или оконных функций, которые сложно или невозможно выразить в JPQL. - Для использования специфичных для СУБД возможностей (например,
JSON-функции в PostgreSQL,MERGEв Oracle). - Для оптимизации критичных по производительности запросов, где требуется точный контроль над планом выполнения.
Примеры использования:
-
С помощью
EntityManager:@PersistenceContext private EntityManager entityManager; public List<User> findUsersOlderThan(int age) { // :age - именованный параметр для защиты от SQL-инъекций String sql = "SELECT * FROM users WHERE age > :age"; Query query = entityManager.createNativeQuery(sql, User.class); query.setParameter("age", age); return query.getResultList(); } -
С помощью Spring Data JPA и аннотации
@Query:@Repository public interface UserRepository extends JpaRepository<User, Long> { // Атрибут nativeQuery = true указывает на нативный запрос @Query(value = "SELECT * FROM users u WHERE u.status = :status", nativeQuery = true) List<User> findByStatusNative(@Param("status") String status); }
| Преимущества и недостатки: | Преимущество | Недостаток |
|---|---|---|
| Полный контроль над SQL. Можно использовать любой синтаксис СУБД. | Потеря переносимости. Запрос привязан к конкретной СУБД. | |
| Возможность тонкой оптимизации. | Сложность поддержки. Запросы не проверяются на этапе компиляции. | |
| Прямой доступ ко всем функциям БД. | Риск SQL-инъекций при неправильном использовании (всегда используйте параметризацию!). | |
| Отсутствие пагинации "из коробки" для сложных запросов (требует ручной доработки). |