@Service
class Impl{
public ResponseEntity<?> find(patientIdList,shapeNameList){
someEntity = repository.findByFilters(patientIdList,shapeNameList);
return someEntity;
}
}
@Entity
@NamedNativeQuery(
name = "MyEntity.findByFilters",
query = "_________________________________",
resultSetMapping = "dummyMapping"
))
@SqlResultSetMapping(
name = "dummyMapping",
...
)
public class ...{
}
когда shapeNameList ПОСТАВЛЯЕТСЯ клиенты оставляют json-ввод, тогда @ Namednativequery.query, упомянутый выше, должен быть: -------------------------------------------------- -------------------------------------------------- -------------------
query = SELECT DISTINCT a.shape_name as shapename, a.patient_id patientId, a.shape_type_id as shapetypeid
FROM pairdb.tbl_sf_density a
WHERE a.patient_id IN( ?1 )
AND a.shapeNameList IN( ?2 ) --this line needs to be dynamically incorporated
group by shapename;
когда shapeNameList НЕ ПОСТАВЛЯЕТСЯ клиенты оставляют json-ввод, тогда @ Namednativequery.query, упомянутый выше, должен быть:
-------------------------------------------------- -------------------------------------------------- -------------------
query = SELECT DISTINCT a.shape_name as shapename, a.patient_id patientId, a.shape_type_id as shapetypeid
FROM pairdb.tbl_sf_density a
WHERE a.patient_id IN( ?1 )
-- AND a.shapeNameList IN( ?2 ) --this line needs to be dynamically omitted from the query within @NamedNativeQuery above
group by shapename;
Я не могу построить идеальное решение для этого динамического изменения части SQL. Может ли кто-нибудь помочь с простым решением Spring JPA?
ИЛИ ЖЕ
Можем ли мы просто манипулировать в postgres SQL с помощью некоторой логики, чтобы переключаться между
'AND a.shapeNameList IN( ?2 ) ' против ' '
с использованием COALSCE / NULLIF / IFNULL / CASE WHEN THEN END ? anything ?
Думаю, это должен быть лучший вариант. Любая помощь приветствуется.





Если вам действительно нужно использовать @NamedNativeQuery, вы также можете создать разные запросы, аннотированные с помощью @NamedNativeQuery, и в сервисе решить, какой из них вызывать в зависимости от данных. Сервис - подходящее место для любой бизнес-логики, такой как решение, какой запрос вызвать.
Я бы также не стал помещать запросы в сущности, а вместо этого использовал бы репозитории.
Итак, набросок решения может быть:
@Repository
interface ShapesRepository {
@Query(...)
List<Shape> findForPatiets(List patientIdList)
@Query(...)
List<Shape> findForPatientsAndNameList(List patientIdList, List names)
}
@Service
class ShapesService{
public find(patientIdList,shapeNameList){
if (isEmpty(shapeNameList)){
repository.findForPatients(patientIdList);
} else {
repository.findForPatientsAndNameList(patientIdList, shapeNameList);
}
}
}
Но на вашем месте я бы серьезно подумал об использовании QueryDSL.
Specification + QueryDSl/Criteria seems heavy for the purpose.
Я не согласен. Поскольку в комментарии к ответу Матеуша вы предлагаете иметь несколько таких параметров, Specification кажется идеальным вариантом.
В подобных случаях также работает поиск по примеру, но он не поддерживает in-clauses.
Если вы хотите рассмотреть аннотации @Query, вы можете использовать поддержку SpEL, напишите что-то вроде этого:
@Query("... where 0 = ?#{param.size} or a.shapeNameList IN :param")
public Something something(List param);
Опечатки в коде - это не ошибка, а средство обучения.
Есть несколько таких Params (скажем, N params), таких как имена в соотв. к твоему примеру. В таком случае, как предполагалось, количество таких разных запросов будет расти экспоненциально, как мощность (2, N).