Сводка
Я хочу выполнить собственный запрос SQL (внутри базы данных Postgresql) из весеннего репозитория, где целые части запроса зависят от заданного параметра.
Справочная информация
Учитывая следующие сущности / таблицы:
employee:
id | name | ...
employee_skill:
employee_id | skill_id | experience_level
skill:
id | name | description
Учитывая Карту от skill_id до experience_level, я должен найти сотрудников, которые обладают всеми данными навыками с наименьшим опытом.
Например, чтобы найти сотрудников, имеющих навык 2 со стажем 2 и навык 68 со стажем 3, мое решение было бы использовать один запрос с реляционным делением :
WITH skillMap as (VALUES (2,2),(68,3))
SELECT e.* from employee as e inner join employee_skill es on e.id = es.employee_id inner join skillMap as sm on es.skill_id = sm.column1
WHERE es.experience_level >= sm.column2
GROUP BY e.id
HAVING COUNT(es.skill_id) >= (SELECT COUNT(*) FROM skillMap);
Этот запрос уже возвращает всех сотрудников, имеющих как минимум 2-й уровень опыта в навыке 2 и 3-й уровень в навыке 68.
Проблема
Проблема заключается в том, что входные данные навыка java должны быть преобразован в строковое представление (key, value), (key, value), ...
и вставлен в первую строку запроса во время выполнения. Но входная строка не может быть введена обычным способом. Следующий код приводит к исключению во время выполнения:
@Query(native=true, value=
"WITH skillMap as :map)
SELECT e.* from employee as e inner join employee_skill es on e.id = es.employee_id inner
join skillMap as sm on es.skill_id = sm.column1
WHERE es.experience_level >= sm.column2
GROUP BY e.id
HAVING COUNT(es.skill_id) >= (SELECT COUNT(*) FROM skillMap);")
List<Employee> findAllBySkillMap(@Param("map") String map)
Причиной исключения является Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Я знаю другие способы вызова запросов. Например, с EntityManager. Но я хотел бы быть настолько последовательным, насколько это возможно, с уже существующими методами в нашем коде.
Вопрос
Каков наилучший / оптимальный способ предоставления этого параметра карты для вышеуказанного запроса? Или, альтернативно, существует ли запрос SQL, который решает ту же проблему и легче интегрируется в Spring?