具有嵌套关联的接口投影

2024-02-11

假设有两个实体:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Author {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String firstName;
  private String lastName;
  @ManyToMany(mappedBy = "authors")
  private Set<Book> books;
}
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String title;
  private String fileName;
  private String fileType;
  @Lob
  private byte[] data;
  @ManyToMany
  @JoinTable(
      name = "book_authors",
      joinColumns = @JoinColumn(name = "book_id"),
      inverseJoinColumns = @JoinColumn(name = "author_id"))
  private Set<Author> authors;
}

以下 DTO 接口投影用于仅查询需要的列。

public interface AuthorView {
    String getFirstName();
    String getLastName();
    Set<BookView> getBooks();
     
    interface BookView {
        String getTitle();
    }
}

一个简单的findAllBy查询方法在存储库中声明:

public interface AuthorRepository extends JpaRepository<Author, Long> {
    @EntityGraph(attributePaths = "books")
    List<AuthorView> findAllBy();
}

该方法执行以下查询:

select
    author0_.id as id1_0_0_,
    book2_.id as id1_1_1_,
    author0_.first_name as first_na2_0_0_,
    author0_.last_name as last_nam3_0_0_,
    book2_.data as data2_1_1_,
    book2_.file_name as file_nam3_1_1_,
    book2_.file_type as file_typ4_1_1_,
    book2_.title as title4_1_1_,
    books1_.author_id as author_i2_2_0__,
    books1_.book_id as book_id1_2_0__ 
from
    author author0_ 
left outer join
    book_authors books1_ 
        on author0_.id=books1_.author_id 
left outer join
    book book2_ 
        on books1_.book_id=book2_.id

即使投影不包含data, file_name, and file_type属性,它们是从数据库中获取的,这会导致性能问题,尤其是在文件很大的情况下。

问题在于 Spring Data JPA 获取整个实体并使用它们来执行编程映射,根据托尔本·詹森的博客 https://thorben-janssen.com/spring-data-jpa-query-projections/.

除了编写大量查询之外,是否有任何解决方案可以防止在使用基于接口的 DTO 投影时获取整个实体?


最近我发现Blaze 持久性 - 实体视图模块 https://persistence.blazebit.com/documentation/1.6/entity-view/manual/en_US/,看起来很有希望。

根据@克里斯蒂安·贝科夫的回答 https://stackoverflow.com/questions/73589164/spring-boot-rest-api-jpa-entities-dtos-what-is-the-best-approach/73606143#73606143, EntityView投影几乎可以像 Spring Data Projections 一样使用Spring 数据集成 https://persistence.blazebit.com/documentation/1.6/entity-view/manual/en_US/#spring-data-features,并且这些投影仅获取必要的属性。此外,无需使用@EntityGraph,因为集成通过调整查询生成来临时处理它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有嵌套关联的接口投影 的相关文章

随机推荐