简体   繁体   English

如何以最少的查询数量获取所有多对多关系?

[英]How to fetch all many-to-many relations in minimum count of queries?

How can I fetch all many-to-many relations using a minimal number of queries? 如何使用最少数量的查询获取所有多对多关系? I mean without any n+1 queries . 我的意思是没有任何n+1 queries 3 - it's normal 3-正常

I have an entity: 我有一个实体:

@Entity
@Table(name = "tags")
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "title")
    private String title;
}

@Entity
@Table(name = "stations")
public class Station {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "title")
    private String title;
}

@Entity
@Table(name = "songs")
public class Song {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "title")
    private String title;

    @ManyToMany
    @JoinTable(
            name = "songs_stations",
            joinColumns = {
                    @JoinColumn(
                            name = "song_id",
                            referencedColumnName = "id"
                    )
            },
            inverseJoinColumns = {
                    @JoinColumn(
                            name = "station_id",
                            referencedColumnName = "id"
                    )
            }
    )
    private List<Station> stations;

    @ManyToMany
    @JoinTable(
            name = "songs_tags",
            joinColumns = {
                    @JoinColumn(
                            name = "song_id",
                            referencedColumnName = "id"
                    )
            },
            inverseJoinColumns = {
                    @JoinColumn(
                            name = "tag_id",
                            referencedColumnName = "id"
                    )
            }
    )
    private List<Tag> tags;
}

And a repository: 还有一个存储库:

public interface SongRepository extends CrudRepository<Song, Long> {

    @Query("SELECT s FROM Song s LEFT JOIN FETCH s.tags LEFT JOIN FETCH s.stations")
    public List<Song> completeFindAllSongs();
}
  • so, I can't use eager loading in completeFindAllSongs() cause of cannot simultaneously fetch multiple bags 所以,我不能在completeFindAllSongs()使用紧急加载,因为cannot simultaneously fetch multiple bags
  • Can't use @NamedEntityGraph 不能使用@NamedEntityGraph
  • And I can't load data manually, because I don't have access to songs_tags table 而且我无法手动加载数据,因为我无权访问songs_tags
  • Please don't advise to use @LazyCollection 请不要建议使用@LazyCollection

What should I do? 我该怎么办?

so, i can't use eager loading in completeFindAllSongs() cause of cannot simultaneously fetch multiple bags 所以,我不能在completeFindAllSongs()中使用紧急加载,因为不能同时获取多个包

This error should go away if you change your entities to use "Set" instead of "List" for OneToMany and ManyToMany relations. 如果您将实体更改为对OneToMany和ManyToMany关系使用“设置”而不是“列表”,则该错误应消失。

Edit: So to answer to your question is: You only need 1 Query. 编辑:所以要回答您的问题是:您只需要1查询。 Just use Sets and eager fetch whatever you want. 只需使用Sets并渴望获取您想要的任何东西。

Keep in mind that by join fetching multiple collections you are creating full Cartesian product between the collection rows which may have a huge negative performance impact both on the database and application side. 请记住,通过联合获取多个集合,您将在集合行之间创建完整的笛卡尔积,这可能会对数据库和应用程序端产生巨大的负面性能影响。

You may want to consider using batch size to initialize the collections in batches. 您可能要考虑使用批处理大小批量初始化集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM