如何以非编程方式动态更改@Namednativequery.query?

How to change the @Namednativequery.query dynamic but non-programatically?

目前情况如何

@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 ...{
}

所需用例:

when shapeNameList IS SUPPLIED by clients rest json input, then @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 NOT SUPPLIED 由客户 rest 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,不妨创建who不同的query,注解@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.

我不同意。由于在对 Mateusz 回答的评论中你建议你有多个这样的参数,Specification 似乎是一个完美的选择。

在类似的情况下,find-by-example 也可以,但它不支持 in-clauses。

如果您愿意考虑 @Query 注释,您可以使用 SpEL 支持编写如下内容:

@Query("... where 0 = ?#{param.size} or a.shapeNameList IN :param")
public Something something(List param);

代码中的拼写错误不是错误,而是训练功能。