【问题标题】:How to make dynamic queries at run-time in Spring Boot and Data?如何在运行时在 Spring Boot 和 Data 中进行动态查询?
【发布时间】:2018-07-16 12:42:07
【问题描述】:

我是 Java 新手,从 Spring Boot 和 Spring Data JPA 开始,所以我知道两种获取数据的方法:

  • byRepository层,字面量方法命名:FindOneByCity(String city);
  • 通过自定义 repo,带有 @Query 注释:@Query('select * from table where city like ?');

两种方式都是静态设计的。

我应该如何获取必须在运行时构建的查询数据?

我想要实现的是无需接触代码即可创建动态报告的可能性。一个表将包含具有名称的报告记录和具有默认参数(如 begin_date、end_date 等)的 SQl 查询,但具有各种主体。示例:

"Sales report by payment method" | select * from sales where met_pay = %pay_method% and date is between %begin_date% and %end_date%;

【问题讨论】:

  • 您能详细说明您想要达到的目标吗?我有点困惑为什么不推荐使用 QueryDsl。愿意发布对此的参考吗?
  • 您的第一点不正确。文字方法命名在存储库层而不是自定义存储库。根据您的要求,您可以创建自定义存储库层并使用 EntityManger 并构建动态查询
  • @mp911de 它在 Spring 文档中说它已弃用,所以我的老板小心不要使用它:docs.spring.io/spring-data/jdbc/docs/current/reference/html/…
  • @PSyLoCKe,QueryDSL 支持已被弃用,仅适用于 Spring JDBC 扩展,不适用于 Spring Data JPA。

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


【解决方案1】:

Criteria API 主要是为此而设计的。
它提供了另一种定义 JPA 查询的方法。
有了它,您可以根据运行时提供的数据构建动态查询。

要使用它,您需要创建一个自定义存储库实现,而不仅仅是一个接口。
您确实需要注入 EntityManager 来创建所需的对象来创建和执行 CriteriaQuery
您当然必须编写样板代码来构建查询并执行它。

This section 解释了如何使用 Spring Boot 创建自定义存储库。


关于您的编辑:

我想要实现的是创建动态的可能性 无需接触代码即可报告。一张表将有以下记录 带有名称的报告和带有默认参数的 SQl 查询,例如 begin_date、end_date 等,但有多种主体。

如果查询是以纯文本文件的形式编写的,Criteria 将不是最佳选择,因为 JPQL/SQL 查询和 Criteria 查询确实不是以相同的方式编写的。
在 Java 代码中,将纯文本文件中定义的 JPQL/SQL 查询映射到 Map<String, String> 结构会更合适。

但是我对你想做的事情的可行性有些怀疑。 查询可能有特定的参数,在某些情况下,除了修改代码,您别无选择。参数中的特殊性将使查询的可维护性变得非常困难并且容易出错。就个人而言,我会通过允许客户为每个字段选择是否应应用条件来实现这一需求。
然后从实现方面,我会使用这个用户信息来构建我的CriteriaQueryCriteria 会做得非常好:更少的代码重复,更好的查询构建适应性以及更多的编译类型检查。

【讨论】:

  • 嗨大卫!我可以用它来实现问题编辑中解释的内容吗?
  • 嘿!我的评论太长了。我更新了我的答案。
  • 谢谢你,我会用你给我的知识。我已经在 2011 年使用 Delphi 制作的另一个应用程序中采用了这种方法。它工作得很好,直到现在它被用来向客户提供许多管理和财务报告。但现在我想更上一层楼,让它成为 Java 中的 Web 应用程序。再次感谢!
  • 嘿。你很受欢迎。祝你的任务好运!
【解决方案2】:

Spring-data 存储库在下面使用 EntityManager。存储库类只是用户不必担心细节的另一层。但是如果用户想弄脏自己的手,那么 spring 当然不会介意。
那是您可以直接使用 EntityManager 的时候。

假设您有一个像 AbcRepository 这样的存储库类

interface AbcRepository extends JpaRepository<Abc, String> {

}

您可以创建一个自定义存储库,如

interface CustomizedAbcRepository {
  void someCustomMethod(User user);
}

实现类的样子

class CustomizedAbcRepositoryImpl implements CustomizedAbcRepository {

@Autowired
EntityManager entityManager;


  public void someCustomMethod(User user) {
    // You can build your custom query using Criteria or Criteria Builder
    // and then use that in entityManager  methods
  }
}

请注意,自定义接口和自定义实现类的命名非常重要

【讨论】:

  • 我不能直接在 JpaRepository 中实现它吗?
  • 嗨,我如何自动装配 CustomizedAbcRepositoryImpl ?
【解决方案3】:

在 Spring Data 的最新版本中添加了使用 JPA Criteria API 的能力。有关更多信息,请参阅博文https://jverhoelen.github.io/spring-data-queries-jpa-criteria-api/

【讨论】:

  • 仅供参考 - 链接已损坏
猜你喜欢
  • 2022-12-05
  • 2018-07-06
  • 2020-11-13
  • 2017-01-15
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
相关资源
最近更新 更多