繁体   English   中英

双向多对多关系中子/父实体的有效获取

[英]Efficient fetching of child/parent entities in a bidirectional many-to-many relationship

我正在开发一个使用mysql数据库的SpringBoot服务。

我的数据库中有三个表:人员,收件人和类别。 人员与类别具有双向的多对多关系,收件人也是如此。 集合延迟加载。

在控制器中,我想概述一下这三个表中的实体。 我在服务层中的代码如下所示:

List<Person> allPersons = personRepository.findAll();
List<Recipient> allRecipients = recipientRepository.findAll();
List<Category> allCategories = categoryRepository.findAll();

for(Person person : allPersons){
    Set<Category> categories = person.getCategories();
    for(Category category : categories){
        // do something with the person and the categories
    }
}

for(Recipient recipient : allRecipients){
    Set<Category> categories = recipient.getCategories();
    for(Category category : categories){
        // do something with the recipient and the categories
    }
}

for(Category category : allCategories){
    Set<Person> persons = category.getPersons();
    for(Person person : persons){
        // do something with the category and the persons
    }
    Set<Recipient> recipients = category.getRecipients();
    for(Recipient recipient : recipients){
        // do something with the category and the recipients
    }
}

在前三行中,在三个数据库查询中,所有必需的实体都会从数据库中加载一次。 从性能的角度来看,这是可以的。 但:

根据记录,在调用例如

Set<Category> categories = person.getCategories()

在第一个外部for循环中,该服务进行另一个数据库查询,以获取每个人的人的类别,尽管类别已经在前三个代码行中加载。 其他循环也是如此。

例如,如果数据库中有5个人,6个收件人和7个类别,则该服务总共执行3 + 5 + 6 + 2 * 7 = 28个数据库查询。 显然,这是非常低效的。

我的问题是:

我必须更改什么,以便该服务仅使用尽可能少的数据库查询就可以提取每个实体一次?

您面临的问题是典型的休眠N + 1问题。您可以急于获取您的集合并编写自己的查询。

@Query("Select p from Person p join fetch p.categories categories)
public List<Person> fetchAllPerson();

您可以阅读有关JPA Hibernate n + 1问题的更多信息(懒惰和渴望的差异)

暂无
暂无

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

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