在我的SpringData应用程序中,我遇到了(N+1)selects问题。
  
  
   我有以下Spring Data实体:
  
  @Entity
@Table(name = "card_categories")
public class CardCategory extends BaseEntity implements Serializable {
    @Id
    @SequenceGenerator(name = "card_categories_id_seq", sequenceName = "card_categories_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "card_categories_id_seq")
    private Long id;
    private String name;
...
}
@Entity
@Table(name = "levels")
public class Level extends BaseEntity implements Serializable {
    @Id
    @SequenceGenerator(name = "levels_id_seq", sequenceName = "levels_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "levels_id_seq")
    private Long id;
    private String name;
...
}
@Entity
@Table(name = "card_categories_levels")
public class CardCategoryLevel extends BaseEntity implements Serializable {
    @Id
    @SequenceGenerator(name = "card_categories_levels_id_seq", sequenceName = "card_categories_levels_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "card_categories_levels_id_seq")
    private Long id;
    @OneToOne
    @JoinColumn(name = "card_category_id")
    private CardCategory cardCategory;
    @OneToOne
    @JoinColumn(name = "level_id")
    private Level level;
...
}
  
   和空的Spring Data存储库:
  
  @Repository
public interface CardCategoryLevelRepository extends JpaRepository<CardCategoryLevel, Long> {
}
  
   当我试图取回所有
   
    CardCategoryLevel
   
   实体
   
    cardCategoryLevelRepository.findAll()
   
   方法,它为我的每一行生成3个SELECT
   
    card_categories_levels
   
   桌子
  
  
   为了使用一个JOIN而不是N+1个SELECT,我重新实现了
   
    CardCategoryLevelRepository
   
   :
  
  @Repository
public interface CardCategoryLevelRepository extends JpaRepository<CardCategoryLevel, Long> {
    @Query(value = "SELECT ccl FROM CardCategoryLevel ccl LEFT JOIN FETCH ccl.cardCategory cc LEFT JOIN FETCH ccl.level l where cc = :cardCategory and l = :level")
    CardCategoryLevel findByCardCategoryAndLevel(@Param("cardCategory") CardCategory cardCategory, @Param("level") Level level);
    @Override
    @Query(value = "SELECT ccl FROM CardCategoryLevel ccl LEFT JOIN FETCH ccl.cardCategory LEFT JOIN FETCH ccl.level")
    List<CardCategoryLevel> findAll();
}
  
   但我不确定我是以正确的最佳方式完成的。
  
  
   请验证我的方法,并告诉它是解决(N+1)个SELECTs问题的最佳解决方法,Spring Data中是否存在OneToOne关联,以及最好的解决方法是什么。
  
  
   我是应该原封不动,还是应该转移到其他抽象……比如QueryDSL之类的?