我看過各種描述 JPA EntityGraph 允許在運行時選擇圖形的帖子。我并不完全清楚這是指什么。
出于善意和尊重,我想將這篇有用的文章作為參考:https ://www.baeldung.com/jpa-entity-graph 。(大多數 JPA 用戶可能已經經歷過。)
文章參考——
EntityGraph 允許對我們想要檢索的相關持久性欄位進行分組,并讓我們在運行時選擇圖形型別。
并在結論部分再次鞏固上述陳述。
在本文中,我們探索了使用 JPA 物體圖來動態獲取物體及其關聯。
決定是在我們選擇加載或不加載相關關聯的運行時做出的。
正如我們在文章 (5.1) 中看到的 - EntityGraphs 使用 Annotations- 5.1 定義如下
。使用注釋定義物體圖
@NamedEntityGraph(
name = "post-entity-graph",
attributeNodes = {
@NamedAttributeNode("subject"),
@NamedAttributeNode("user"),
@NamedAttributeNode("comments"),
}
)
@Entity
public class Post {
@OneToMany(mappedBy = "post")
private List<Comment> comments = new ArrayList<>();
//...
}
@NameEntityGraph 注釋是在編譯時定義的,我在這里看不到任何運行時或動態的東西。
但在 5.2 中- 物體圖是使用 api 或以編程方式定義的 -
5.2。使用 JPA API 定義物體圖
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
entityGraph.addAttributeNodes("subject");
entityGraph.addAttributeNodes("user");
在 5.2 方法中,我看到可以使用一些邏輯動態選擇節點。這種方法就是所謂的“動態獲取”和“基于運行時”。 還是我錯過了什么,我還有更多要了解的東西。
進一步使用 6. 中給出的方法。使用物體圖
ex:
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);
都是程式化的,因此可以在運行時更改,即它們可以說是動態的。
但是在上面的文章中遺漏了一種方法,但在這里提到了 - https://www.baeldung.com/spring-data-jpa-named-entity-graphs,如下所示,似乎不符合動態標準。
public interface ItemRepository extends JpaRepository<Item, Long> {
@EntityGraph(value = "Item.characteristics")
Item findByName(String name);
}
動態方法是否僅指 5.2 樣式,或者它也暗示 5.1 樣式。
uj5u.com熱心網友回復:
您不能將動態物體圖與 spring-data 一起使用,因為JpaRepository沒有方法來傳遞物體圖,例如
Optional<T> findById(ID id, EntityGraph entityGraph);
使用自定義 JPA 存盤庫
您可以為此使用原始 JPA,方法是創建自定義存盤庫并使用帶有EntityManager.
使用 spring-data-jpa-entity-graph
使用庫 spring-data-jpa-entity-graph有一種更方便的方法。
它允許使用 JPA 存盤庫方法,例如動態物體圖findById()或findByName()與動態物體圖一起使用。
我更喜歡將它與這個助手類一起使用
public abstract class EntityGraphBuilder<T> {
private List<String> result = new ArrayList<>();
protected T self;
public T add(String path) {
result.add(path);
return self;
}
public DynamicEntityGraph build() {
return new DynamicEntityGraph(EntityGraphType.FETCH, result);
}
}
每個物體都有自己的GraphBuilder
@Entity
public class OrderEntity {
@Id
private Long id;
@Column
private name;
@ManyToOne(fetch = FetchType.LAZY)
private OrderRequestEntity orderRequest;
@ManyToOne(fetch = FetchType.LAZY)
private ProviderEntity provider;
public static GraphBuilder graph() {
return new GraphBuilder();
}
public static class GraphBuilder extends EntityGraphBuilder<GraphBuilder> {
private GraphBuilder() {
self = this;
}
public GraphBuilder orderRequest() {
return add("orderRequest");
}
public GraphBuilder provider() {
return add("provider");
}
}
}
庫EntityGraphJpaRepository中的存盤spring-data-jpa-entity-graph庫使用
@Repository
public interface OrdersRepository extends EntityGraphJpaRepository<OrderEntity, Long> {
OrderEntity findByName(String name, EntityGraph entityGraph);
}
您也可以使用派生查詢方法findByName(),例如動態物體圖。
使用方法的例子findById(),同樣的方法可以應用到findByName()
OrdersRepository ordersRepository;
Long orderId = 1L;
OrderEntity order = ordersRepository.findById(
orderId,
OrderEntity.graph().orderRequest().provider().build()
).orElseThrow(
() -> new ServiceException("Can't find orderId=" orderId)
);
uj5u.com熱心網友回復:
在 Baeldung 文章中,第 5 節僅介紹了定義圖的各種方法,并沒有過多強調定義本身的動態/非動態性質。
在第 5.1 節中,圖的定義是靜態的,但本節僅演示如何定義一個圖,然后在動態構建圖并不是真正必要的典型情況下使用該圖。本節顯示了使用 JOIN FETCH 節構建 HQL / JPA-QL 查詢的舊方法的替代方法。
@NamedEntityGraph(
name = "post-entity-graph",
attributeNodes = {
@NamedAttributeNode("subject"),
@NamedAttributeNode("user"),
@NamedAttributeNode("comments"),
}
)
@Entity
public class Post {
@OneToMany(mappedBy = "post")
private List<Comment> comments = new ArrayList<>();
//...
}
然后,第 6 節告訴您如何以各種方式使用前面定義的物體圖。
// Getting the "statically" defined graph (from annotation)
EntityGraph entityGraph = entityManager.getEntityGraph("post-entity-graph");
// Then using the graph
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);
當然,您可以將第一行替換為第 5.2 節中演示的完全動態構建的圖:
// Building the graph dynamically
EntityGraph<Post> entityGraph = entityManager.createEntityGraph(Post.class);
entityGraph.addAttributeNodes("subject");
entityGraph.addAttributeNodes("user");
// Then using the graph
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
Post post = entityManager.find(Post.class, id, properties);
在這兩種情況下,您都向查詢提供EntityGraph物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/429909.html
