簡體   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