首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据接收到的参数使用JPA创建具有分页结果的自定义动态查询

如何根据接收到的参数使用JPA创建具有分页结果的自定义动态查询
EN

Stack Overflow用户
提问于 2020-10-24 02:20:13
回答 2查看 80关注 0票数 1

我想基于在我的searach API端点中接收到的参数来构建一个动态JPA查询,可能有3个参数: nome,cidade,causas (作为一个可以传递多个数字的数组):

代码语言:javascript
复制
@GetMapping("/search")
    public ResponseEntity<?> findByNome(Pageable pageable,
                                        @RequestParam Optional<String> nome,
                                    @RequestParam Optional<Long[]> causas,
                                    @RequestParam Optional<Long> cidade){

有了这3个参数,我需要使用6种可能的查询组合:*仅传递cidade *仅传递cidade和causas *仅使用nome和causas *cidade和nome *cidade、nome和causas

为了达到同样的效果,我现在这样做:

代码语言:javascript
复制
 @Repository
public interface InstituicaoRepository extends PagingAndSortingRepository<Instituicao, Long> {

    //*only cidade passed
    Page<Instituicao> findByCidadeId(long cidadeId, Pageable pageable);
    //*cidade and causas
    @Query("select i from Instituicao i where i.cidadeId = ?1 and i.causaId in (?2)")
    Page<Instituicao> findByCidadeIdAndCausaIds(long cidadeId, Long[] causaIds, Pageable pageable);

    //*only nome
    Page<Instituicao> findByNomeContainingIgnoreCase(String nome, Pageable pageable);
    //*nome and causas
    @Query("select i from Instituicao i where lower(i.nome) like lower(concat('%',?1,'%')) and i.causaId in (?2)")
    Page<Instituicao> findByNomeAndCausaIds(String nomeInstituicao, Long[] causaIds, Pageable pageable);

    //*cidade and nome
    @Query("select i from Instituicao i where i.cidadeId = ?1 and lower(i.nome) like lower(concat('%',?2,'%'))")
    Page<Instituicao> findByCidadeIdAndNome(long cidadeId, String nomeInstituicao, Pageable pageable);
    //*cidade, nome and causas
    @Query("select i from Instituicao i where i.cidadeId = ?1 and lower(i.nome) like lower(concat('%',?2,'%')) and i.causaId in (?3)")
    Page<Instituicao> findByCidadeIdAndNomeAndCausaIds(long cidadeId, String nomeInstituicao, Long[] causaIds, Pageable pageable);

}

为了调用每个invoke parameters的方法,我手动使用ifs来检查哪些参数存在,哪些参数不存在(这让我在每次查看代码时都想哭)

有什么建议可以改进这一点,使其更有效率?请注意,需要包括JPA的分页。

EN

回答 2

Stack Overflow用户

发布于 2020-10-24 04:20:57

你的方法不是很好,因为你的存储库中有很多方法,它会随着时间的推移而增长,这在Spring.io中已经提到了,解决这个问题的更好的方法是使用Specification,你可以从JpaSpecificationExecutor扩展你的存储库,并传递从其他层执行的规范,它更干净,使你的代码易于阅读。甚至还有一种更好的方法,那就是querydsl,在这种方法中,你甚至不需要指定Specification,Spring data本身就可以为你处理许多情况。请阅读以下来自Spring本身的链接:advanced-spring-data-jpa-specifications-and-querydsl

票数 2
EN

Stack Overflow用户

发布于 2020-10-30 13:22:14

我已经开发了一个名为spring-dynamic-jpa的库,它使使用JPA实现动态查询变得更容易。

您可以使用它来编写查询模板。查询模板在执行之前将被构建到不同的查询字符串中,具体取决于调用该方法时的参数。

代码语言:javascript
复制
public interface InstituicaoRepository extends JpaRepository<Instituicao, Long> {
    @DynamicQuery("select i from Instituicao i\n" +
            "<@where>\n" +
            "   <#if cidadeId??>\n" +
            "       i.cidadeId = :cidadeId\n" +
            "   </#if>\n" +
            "   <#if nomeInstituicao??>\n" +
            "       and lower(i.nome) like lower(concat('%',:nomeInstituicao,'%'))\n" +
            "   </#if>\n" +
            "   <#if causaIds??>\n" +
            "       and i.causaId in :causaIds\n" +
            "   </#if>\n" +
            "</@where>")
    Page<Instituicao> findInstituicao(Long cidadeId, String nomeInstituicao, List<Long> causaIds, Pageable pageable);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64505441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档