繁体   English   中英

Spring Data JPA具有多个联接的多个可选搜索参数

[英]Spring Data JPA Multiple Optional Search Parameters With Multiple Joins

我目前正在使用Spring Boot和Spring Data JPA来连接到oracle数据库。 通过一个参数,我只使用Spring Repository findById(Long id); 而且效果很好。 另一方面,搜索对我来说要复杂得多。 在我们的例子中,用户为嵌套的JSON对象提供了多个可选的搜索参数(目前,我无法更改其通过嵌套JSON发送数据的方式)。 JSON输入对象如下所示:

{
  "agent_filter": {
    "first_name": "string",
    "last_name": "string",
    "agentNumber": "string",
    "agentCode": "string"
  },
  "account": "string",
  "status": "string",
  "paid": "string",
  "amount": "string",
  "person_filter": {
    "date_of_birth": "string",
    "first_name": "string",
    "last_name": "string",
    "tax_id": "string"
  }
}

所有搜索条件都是可选的(至少1个参数除外)

在后端,我们具有以下实体:

@Entity
Account{
@OneToMany
List<PersonRole> role;

@OneToMany
List<AgentRole> role;
}

@Entity
PersonRole{
String role;

Person person;
}

@Entity
AgentRole{
String role;

Agent agent;
}

@Entity
Person{...}

@Entity
Agent{...}

因此,要提供搜索功能,我可以进行多个联接。 我开始使用带有@Query表示法的JPQL,但是我必须做的is null or检查每个参数,这很麻烦。 我开始研究其他选项,并且看到了有关QueryDSL,标准,规范的信息,但是我不确定应该重点关注哪一个。 不幸的是,我对这个主题并不了解很多,我希望有人可以指出正确的方向,以便更好地实现此搜索。 谢谢!

QueryDSL ftw!

当我遇到一个与您非常相似的问题时,让我给您一个示例代码,因为我有很多东西要过滤,其中很多可能为空。

顺便说一句,如果您需要精美的连接,那么您可能将直接使用查询dsl。 这些示例是针对QueryDSL 3的,因此您可能不得不为QueryDSL 4进行更改。因为您已经提到了“如何提供搜索功能以便我可以进行多个联接”,您可能需要直接使用QueryDSL。

首先,您创建自己和BooleanBuilder,然后执行以下操作:

BooleanBuilder builder = new BooleanBuilder();
QContent content = QContent.content;
if (contentFilter.headlineFilter == null || contentFilter.headlineFilter.trim().length() == 0) {
        // no filtering on headline as headline filter = null or blank
    } else if (contentFilter.headlineFilter.equals(Filter.NULL_STRING)) {
        // special case when you want to filter for specific null headline
        builder.and(content.label.isNull());
    } else {
        try {
            long parseLong = Long.parseLong(contentFilter.headlineFilter);
            builder.and(content.id.eq(parseLong));
        } catch (NumberFormatException e) {
            builder.and(content.label.contains(contentFilter.headlineFilter));
        }
    }
    if (contentFilter.toDate != null) {
        builder.and(content.modifiedDate.loe(contentFilter.toDate));
    }
    if (contentFilter.fromDate != null) {
        builder.and(content.modifiedDate.goe(contentFilter.fromDate));
    }

因此,根据您是否拥有每个字段,可以将其添加到过滤器中。

为了使它起作用,您将需要生成Query DSL元数据-使用com.mysema.query.apt.jpa.JPAAnnotationProcessor注释处理器完成。 它生成上面的QContent.content东西。

该BooleanBuilder是谓词的子类。

但是,使用查询dsl,条件,规范是不错的方法,但需要学习它们。

仅使用JpaRepository即可解决您的问题。 您的AccountRepository可能正在扩展JpaRepository ,后者又扩展了QueryByExampleExecutor

QueryByExampleExecutor提供了诸如findOne(Example<S> example)findAll(Example<S> example) ,这些方法将根据传递的Example对象返回结果。

创建Example很简单

Person person = new Person();                         
person.setFirstname("Dave");                          

Example<Person> example = Example.of(person); 

这将匹配所有具有firstName = Dave Person

通过示例阅读更多关于Spring Data Query的信息

您需要使用自定义查询来创建自己的搜索查询。

@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

现在您可以根据需要添加任意数量的参数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM