如何在Spring Boot和Data中的运行时进行动态查询?

时间:2018-02-06 12:36:00

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

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

  • by Repository图层,使用Literal方法命名:FindOneByCity(String city);
  • 通过自定义repo,使用@Query注释:@Query('select * from table from 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%;

3 个答案:

答案 0 :(得分:3)

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

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

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

关于您的修改:

  

我想要实现的是创造动态的可能性   报告没有触及代码。一张表有记录   使用默认参数报告名称和SQl查询   begin_date,end_date等,但有各种各样的主体。

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

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

答案 1 :(得分:1)

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

我们假设您有一个像AbcRepository

这样的Repository类
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
  }
}

请注意,定制界面和自定义实现类的命名非常重要

答案 2 :(得分:1)

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