【问题标题】:`org.springframework.data.jpa.domain.Specification` without parsing the complex query`org.springframework.data.jpa.domain.Specification` 不解析复杂查询
【发布时间】:2021-09-22 00:28:42
【问题描述】:

在我正在开发的 Spring Boot api 中,查询过滤器已准备好从客户端进入,以便进入 where 子句 要通过存储库进行的 jpa(或者更确切地说是 sql)查询。

例如。假设有一个 Book 实体,其字段为 titleauthoredition。 所有Book-s 都将使用过滤器String like 进行查询

String str = "title = 'cooking' or 'recipes' and edition > 5"; 

这个子句可以直接输入到where子句中,如下:

select *
from book
where title = 'cooking' or 'recipes' and edition > 5 ;

问题是,如何直接从这个查询过滤字符串创建org.springframework.data.jpa.domain.Specification?是否可以从 str 创建一个 Specification 实例,而无需以任何方式解析/处理它?

我将对结果进行分页。因此,对 jpa 的EntityManager 的显式调用是行不通的。它必须在存储库中。

TIA。

【问题讨论】:

    标签: java sql spring-boot filter spring-data-jpa


    【解决方案1】:

    使用 JPA NamedQuery 怎么样? 你可以在仓库接口中声明。

    您的示例查询可以转换为

    Page<Book> findAllByTitleInAndEditionGraterThan(List<String> titleList, int editionNo, Pageable pageable);
    

    Check this link, description about JPA named query

    【讨论】:

    • 查询是动态的——在运行时进入并且可以是任何形式。这远不符合要求
    • 那么使用QueryDSL怎么样?我认为它可以解决您的问题。
    • @Query 也不是动态绑定的
    • QueryDSL 是一种通过 JPA 风格进行动态查询的插件。您需要添加依赖项,但我很确定它会对您的问题有所帮助。
    【解决方案2】:

    是否可以从 str 创建规范实例而无需以任何方式解析/处理它?

    不,没有。 做这样的事情是一个非常糟糕的主意。

    1. 从设计的角度来看,您在前端和持久层之间引入了极强的耦合。非常糟糕的主意。

    2. 从安全的角度来看,您基本上是在描述通过字符串连接组装 SQL 语句,这会导致 SQL 注入漏洞。非常非常糟糕的主意。

    【讨论】:

    • 不确定我会做什么——可能和我设计它时所做的一样。肯定会考虑 sql 内容检查器/验证器的可行性—— sql 从现在开始就一直存在,它的查询解析器也是如此。不过现在,我肯定会在规范上搭便车。对原型的不同关注点。有些事情应该留给开发者选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    相关资源
    最近更新 更多