如何在JPA存储库中编写动态查询?使用Java springboot。规范是答案吗?

sha*_*999 4 java dynamic spring-data-jpa spring-boot

我在 JPA 存储库中有一个项目。我想使用 UNIONS 和响应参数从两个表中检索值,并且我成功执行了以下本机查询。

\n
Public interface resultRepository extends JpaRepository<Result, String>{\n\n\n@Query(value= \xe2\x80\x9cSELECT \xe2\x80\x98This is from Table 1\xe2\x80\x99 AS MSG, COLUMN1, COLUMN2 COLUMN3, COLUMN4, COLUMN5 FROM TABLE1 \nWHERE COLUMN1 = :column1 AND COLUMN2 = :column2 AND COLUMN3 = :column3 \nUNION\nSELECT \xe2\x80\x98This is from Table 2\xe2\x80\x99 AS MSG, COLUMN1, COLUMN2 COLUMN3, COLUMN4, COLUMN5 FROM TABLE2\nWHERE COLUMN1 = :column1 AND COLUMN2 = :column2 AND COLUMN3 = :column3 \xe2\x80\x9d, nativeQuery = true)\nList<Result> getResultByParameters(@Param(\xe2\x80\x9ccolumn1\xe2\x80\x9d) String column1, \n    @Param(\xe2\x80\x9ccolumn2\xe2\x80\x99)String column2,@Param(\xe2\x80\x9ccolumn3\xe2\x80\x99) String column3);\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我的问题是。我希望 \xe2\x80\x9cWhere\xe2\x80\x9d 子句是动态的。这样他们就可以通过任何这些参数进行搜索。无论是column1和column2还是column2和column3。在我的前端中,这些列参数将为 NULL。使用本机查询我无法决定选择哪些参数正在使用什么。

\n

我正在阅读此链接中的规范。\n https://dimitr.im/writing-dynamic-queries-with-spring-data-jpa

\n

但我根本不明白\xe2\x80\x99。我仍然可以拥有自定义消息 (MSG) 吗?或者甚至使用联合搜索多个表?

\n

Jig*_*tri 6

因此在 JPA 中创建动态查询的方法有很多种。让我们首先列出其中的一些:

\n
    \n
  1. 自定义存储库
  2. \n
  3. 规格
  4. \n
  5. JPA 存储库本身中的自定义查询(您已经编写过,但我将向您展示更灵活的解决方法)
  6. \n
  7. 查询DSL
  8. \n
\n

自定义存储库

\n

在这种方法中,基本上您创建一个接口,并在其中声明自定义方法。然后将此接口扩展为实际的存储库接口,并手动实现。这是处理自定义查询的最灵活的方式。下面是示例:

\n
public interface CustomRepository {\n    public Result myCustomQueryMethod(String params);\n}\n\npublic interface ResultRepository extends JpaRepository<Result, Long>, CustomRepository { ... }\n\npublic class CustomRepositoryImpl implements CustomRepository {\n\n    @Autowired //@PersistentContext\n    private EntityManager entityManager;\n    \n    public Result myCustomQueryMethod(String params) {\n        String nativeSql = "...";\n        // create query, execute it, and transform the results to object using object mapper or manually\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

规格

\n

下一个是规格(正如您已经提到的)。我不会在这里对规格进行深入解释,因为它已经在您共享的教程链接中进行了解释。但是,如果您不想自己编写 SQL,您可以使用规范创建动态查询。但我猜你不能有自定义投影(自定义选择子句,如你想要的 MSG 参数)和规范。

\n

JPA 存储库中的自定义查询

\n

下面是您的查询的稍微修改版本,如果您要搜索的参数数量(在 where 子句中)固定,则它可以满足您的目的:

\n
@Query(value= \xe2\x80\x9cSELECT \xe2\x80\x98This is from Table 1\xe2\x80\x99 AS MSG, COLUMN1, COLUMN2 COLUMN3, COLUMN4, COLUMN5 FROM TABLE1 \nWHERE (:column1 is null or COLUMN1 = :column1) AND (:column2 is null or COLUMN2 = :column2) AND (:column3 is null or COLUMN3 = :column3)\nUNION\nSELECT \xe2\x80\x98This is from Table 2\xe2\x80\x99 AS MSG, COLUMN1, COLUMN2 COLUMN3, COLUMN4, COLUMN5 \nFROM TABLE2\nWHERE (:column1 is null or COLUMN1 = :column1) AND (:column2 is null or COLUMN2 = :column2) AND (:column3 is null or COLUMN3 = :column3) \xe2\x80\x9d, nativeQuery = true)\nList<Result> getResultByParameters(@Param(\xe2\x80\x9ccolumn1\xe2\x80\x9d) String column1, \n@Param(\xe2\x80\x9ccolumn2\xe2\x80\x99)String column2,@Param(\xe2\x80\x9ccolumn3\xe2\x80\x99) String column3);\n
Run Code Online (Sandbox Code Playgroud)\n

看看我对 where 子句做了什么。

\n

查询DSL

\n

它又与 Criteria API 类似,但语法不同且更简单。您也可以使用 QueryDSL 创建类型安全的动态查询。这是更详细地解释 QueryDSL 的链接 - https://www.baeldung.com/querydsl-with-jpa-tutorial

\n