1. 程式人生 > 實用技巧 >JPA N+1

JPA N+1

@Query("select e from Employee e")
@EntityGraph(value = "graph.Employee.assignments", type = EntityGraph.EntityGraphType.FETCH)
List<Employee> findAllWithAssignments();

@Query("select e from Employee e")
@EntityGraph(value = "graph.Employee.absences", type = EntityGraph.EntityGraphType.FETCH)
List<Employee> findAllWithAbsences();

在很多情況下,我們使用Spring-Data-Jpa,一些簡單的查詢,我們都喜歡用定義方法查詢,而不是寫JPQL。JPA為我們提供了一組註解:使用Spring-Data-Jpa為我們提供的@EntityGraph,或@EntityGraph和@NamedEntityGraph進行解決。

@NamedEntityGraphs、@NamedEntityGraph、@EntityGraph

@NamedEntityGraphs:用於對@NamedEntityGraph註解進行分組。

@NamedEntityGraph:用於指定查詢操作或查詢的路徑和邊界。

    屬性name:(可選) 實體圖的名稱。 預設為根實體的實體名。

    屬性attributeNodes:(可選) 包含在該圖中的實體屬性列表。
    屬性:includeAllAttributes:(可選)將註釋實體類的所有屬性作為屬性節點包含在NamedEntityGraph中,而無需顯式列出它們。包含的屬性仍然可以由引用子圖的屬性節點完全指定。預設為false。一般不需要設定。
    屬性subgraphs:(可選)包含在實體圖中的子圖列表。這些是從NamedAttributeNode定義中按名稱引用的。
    屬性subclassSubgraphs:(可選) 子圖列表 這些子圖將向實體圖添加註釋實體類的子類的附加屬性。超類中的指定屬性包含在子類中。

@EntityGraph: 註解用於配置 JPA 2.1規範支援的javax.persistence.EntityGraph,應該使用在repository的方法上面。從1.9開始,我們支援動態EntityGraph定義,允許通過attributePaths()配置自定義fetch-graph。如果指定了attributePaths(),則忽略entity-graph的name(也就是配置的value()),並將EntityGraph視為動態的。

    屬性value:要使用的名稱。如果為空,則返回JpaQueryMethod.getNamedQueryName()作為value。一般為@NamedEntityGraph的name值,或者不填使用自己的attributePaths屬性。
    屬性type:要使用的EntityGraphType,預設為EntityGraphType.FETCH。
    屬性attributePaths:要使用的屬性路徑,預設為空。可以直接引用實體屬性,也可以通過roperty.nestedProperty引用巢狀屬性。
    列舉EntityGraphType:
      LOAD("javax.persistence.loadgraph"):當javax.persistence.loadgraph屬性用於指定實體圖時,由實體圖的attributePaths指定的屬性將被視為FetchType.EAGER,未指定的屬性,將根據其設定的或預設的FetchType來進行處理。
      FETCH("javax.persistence.fetchgraph"):當javax.persistence.fetchgraph屬性用於指定實體圖時,由實體圖的attributePaths指定的屬性將被視為FetchType.EAGER,而未指定的屬性被視為FetchType.LAZY。