簡體   English   中英

如何在 Spring Boot 中動態獲取 EntityGraph

[英]How to fetch EntityGraph dynamically in Spring Boot

我正在使用 JPA 使用 Spring Boot 開發應用程序。 在應用程序中,我公開了一個休息 API。 我不想使用 Spring data rest,因為我想完全控制數據。

我無法弄清楚如何動態使用 EntityGraph。

假設我有以下模型取自here

   @Entity
class Product {

  @ManyToMany
  Set<Tag> tags;

  // other properties omitted
}

interface ProductRepository extends Repository<Customer, Long> {

  @EntityGraph(attributePaths = {"tags"})
  Product findOneById(Long id);
}

我有以下休息鏈接來訪問產品http://localhost:8090/product/1

它返回給我一個 ID 為 1 的產品

問題:

  1. 它會默認獲取我們提到的@EntityGraph 的標簽嗎? 如果是,那么可以按需配置嗎? 說,如果在查詢字符串中我有include=tags ,那么我只想獲取帶有標簽的產品。

我找到了這篇文章,但不確定這有什么幫助。

Spring Data JPA Repository 中 EntityGraph 的定義是靜態的。 如果您想讓它動態化,您需要像在鏈接到的頁面中那樣以編程方式執行此操作:

EntityGraph<Product> graph = this.em.createEntityGraph(Product.class);
graph.addAttributeNodes("tags"); //here you can add or not the tags

Map<String, Object> hints = new HashMap<String, Object>();
hints.put("javax.persistence.loadgraph", graph);

this.em.find(Product.class, orderId, hints);

您也可以使用 JPA 存儲庫中的 EntityGraph 定義方法。

interface ProductRepository extends Repository<Product, Long> {

@EntityGraph(attributePaths = {"tags"})
@Query("SELECT p FROM Product p WHERE p.id=:id")
Product findOneByIdWithEntityGraphTags(@Param("id") Long id);
}

然后在您的服務中有一個方法,該方法將此方法與 EntityGraph 或內置findOne(T id)而無需 EntityGraph:

Product findOneById(Long id, boolean withTags){
  if(withTags){
    return productRepository.findOneByIdWithEntityGraphTags(id);
  } else {
    return productRepository.findOne(id);
  }
}

您可以在運行時通過使用Spring Data JPA EntityGraph 選擇 EntityGraph
設置非常簡單:

  • 添加: implementation 'com.cosium.spring.data:spring-data-jpa-entity-graph:2.0.7'到 build.gradle
  • 添加: @EnableJpaRepositories(repositoryFactoryBeanClass = EntityGraphJpaRepositoryFactoryBean.class) @SpringBootApplication @EnableJpaRepositories(repositoryFactoryBeanClass = EntityGraphJpaRepositoryFactoryBean.class)波紋管@SpringBootApplication

現在,您可以在運行時選擇最佳 EntityGraph。 示例(這是來自Spring Data JPA EntityGraph的示例):

// This will apply 'Product.brand' named EntityGraph to findByLabel
productRepository.findByLabel("foo", EntityGraphs.named("Product.brand"));

// This will apply 'Product.supplier' named EntityGraph to findByLabel
productRepository.findByLabel("foo", EntityGraphs.named("Product.supplier"));

// This will apply 'supplier' attribute paths EntityGraph (don't need to define named EntityGraph) to findByLabel
productRepository.findByLabel("foo", EntityGraphUtils.fromAttributePaths("supplier"));

請閱讀文檔以獲取更多信息。

您可以在存儲庫中執行此操作:

interface ProductRepository extends Repository<Product, Long> {

    Product findOneById(Long id);

    @EntityGraph(attributePaths = {"tags"})
    Product findOneWithTagsById(Long id);
}

並按照 Robert Niestroj 的建議創建服務方法。

您可以添加如下實體圖,確保實體產品類與標簽類有關系。

@EntityGraph(attributePaths = {
        "tags"
    })
@Query( value = "select product from product)
List<Product> findAllProduct();

暫無
暫無

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

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