Использование enum параметра в JpaRepository nativeQuery
Быстрый ответ
В JpaRepository чтобы работать с enum, их следует преобразовать с использованием name()
или ordinal()
. Это позволит интерпретировать их как String или Integer, которые применимы в SQL:
@Query(value = "SELECT * FROM your_table WHERE status = :status", nativeQuery = true)
List<YourEntity> findByStatus(@Param("status") String status);
// Пример использования enum:
List<YourEntity> result = repository.findByStatus(YOUR_ENUM_CONSTANT.name());
Применение Spring Expression Language (SpEL)
С применением Spring Expression Language (SpEL) запросы становятся более гибкими:
@Query(value = "SELECT * FROM your_table WHERE status = CAST(:#{#status.name()} AS varchar)", nativeQuery = true)
List<YourEntity> findByStatus(@Param("status") ApplicationStatus status);
Enum можно передавать напрямую в findByStatus
, и позволить Spring выполнить преобразование.
Работа с enum типами на стороне SQL базы данных
При использовании enum типов в базе данных, приведение типов поможет прямо в @Query
:
CAST(:#{#status.name()} AS enum_type)
Особенности работы с коллекциями enums
Чтобы применить список enums в запросе, вы можете использовать возможности проекции Spring:
@Query(value = "SELECT * FROM your_table WHERE status IN :statuses", nativeQuery = true)
List<YourEntity> findByStatuses(@Param("statuses") Collection<String> statuses);
// Обработка списков Enums
List<YourEntity> result = repository.findByStatuses(YOUR_ENUMS.stream().map(Enum::name).collect(Collectors.toList()));
Преобразование Enums в строки произойдет автоматически.
Учет nullable enum параметров
В случае, когда enum параметр может иметь значение null, следует использовать этот подход:
:#{#paramName != null ? #paramName.name() : 'DEFAULT_VALUE'}
Таким образом, если значение не равно null, оно будет использовано, иначе будет подставлено значение по умолчанию.
Визуализация
Визуализируем:
Enums в SQL запросе:
- NativeQuery с Enum параметром: возможность его использования.
- JpaRepository: Java требует конкретного значения (код цвета).
Практический пример:
@Query(value = "SELECT * FROM художники WHERE стиль = :стиль", nativeQuery=true)
List<Художник> findByStyle(@Param("стиль") String стиль); // SQL требует строковое представление
Если ваш Enum – это 🖌️, а SQL база данных — это 🎨, вам нужно работать с именами.
Лучшие практики и затруднительные ситуации
Соответствие имен Enum
Имена enum должны соответствовать значениям в базе данных, чтобы избежать путаницы.
Используйте JPQL
Если нативные запросы кажутся сложными, то JPQL может служить альтернативой, поскольку позволяет использовать enum напрямую без преобразований:
@Query("SELECT e FROM Entity e WHERE e.status = :status")
List<YourEntity> findByStatus(@Param("status") ApplicationStatus status);
Используйте SpEL с осторожностью
Не злоупотребляйте SpEL, чтобы запросы оставались ясными и понятными.
Полезные материалы
- Официальная инструкция по использованию
@Query
в Spring Data JPA. - Лучшие практики по маппингу enum с JPA и Hibernate от Влада Михалчи.
- Инструкция по использованию параметров запросов в JPA, включая enums.
- Официальная инструкция по JPQL.
- Видео на Youtube о расширенных техниках запросов JPA, включая enum'ы.