簡體   English   中英

如何在實體之間創建 JPA 規范連接

[英]How to create JPA Specification join between entities

我想根據 JPA 規范創建過濾器。 我正在使用 spring-data。

我的實體:

public class Section {

    /*some other fields*/

    @OneToMany
    @JoinTable(
            name = "section_objective",
            joinColumns = @JoinColumn(name = "section_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "objective_id", referencedColumnName = "id")
    )
    private List<Objective> objectives;

}
public class Objective {

    /*some other fields*/

    @OneToMany
    @JoinTable(
            name = "objective_question",
            joinColumns = @JoinColumn(name = "objective_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "question_id", referencedColumnName = "id")
    )
    private List<Question> questions = new ArrayList<>();
}
public class Question {

    /*some fields, below code is not important*/

}

實體依賴項是:部分- 一對多 ->目標- 一對多 ->問題實體沒有關於父關系的信息(例如,我不能從問題到目標的 go 問題在 Java 代碼中分配給目標)。

我有一個轉換為規范的問題過濾器 class。 我想在部分得到所有問題。

通常我會使用下面寫的 SQL 查詢來獲取部分中的所有問題。

SELECT q.*
FROM
  question q
JOIN
  objective_question oq ON oq.question_id = q.id
JOIN
  objective o ON o.id = oq.objective_id
JOIN
  section_objective so ON so.objective_id = o.id
JOIN
  section s ON s.id = so.section_id
WHERE
  s.id IN (1,2);

我嘗試使用 Join 創建規范,但不知道如何在對 Objective on Question 的引用不可用時創建連接。

Specification.<Question>where((root, query, criteriaBuilder) ->
        root.join("section") /*throws error because **section** is not a part of attribute on Question */
                .in(List.of(1L, 2L)));

您可以使用以下庫: https://github.com/turkraft/spring-filter

它可以讓您運行搜索查詢,例如:

/search?filter= average (ratings) > 4.5 and brand.name in ('audi', 'land Rover') and (year > 2018 or km < 50000) and color : 'white' and事故為空

即使您沒有 API,您也可以運行搜索查詢,該庫基本上會將搜索輸入編譯到 JPA 謂詞或規范(如果您願意的話)。 它將順利處理您所有的連接查詢,而不必擔心眾所周知的 n+1 查詢問題。

您可以按以下方式構建規范:

import static com.turkraft.springfilter.FilterBuilder.*;
Specification<Section> spec = new FilterSpecification<Section>(
  and(
    in("id", numbers(1, 2, 3)),
    equal("objectives.questions.field", "some value")
  )
);
// basically telling: get the sections which have id 1, 2 or 3, AND which have the field 'field' of the objectives questions' equal to 'some value'

您不需要配置任何東西,只需導入依賴項:

<dependency>
    <groupId>com.turkraft</groupId>
    <artifactId>spring-filter</artifactId>
    <version>1.0.2</version>
</dependency>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM