我有两个实体Group和Person,我使用双向映射,在这种情况下我有n + 1个查询而不是一个。
public class Person extends BaseBean {
Group group ;
//getter and setter
}
public class Groupextends BaseBean {
List<Person> childPersons;
//getter and setter
}
我使用eclipselink进行映射。
<entity name="person" class="tn.waycon.alquasar2.gp.model.Person">
<attributes>
<many-to-one name="group" fetch="EAGER">
<join-column name="group_id" />
</many-to-one>
</attributes>
</entity>
<entity name="group_of_persons" class="tn.waycon.alquasar2.gp.model.Group">
<attributes>
<one-to-many name="childPersons" mapped-by="group" fetch="EAGER">
<join-fetch>OUTER</join-fetch>
<cascade>
<cascade-all />
</cascade>
</one-to-many>
</attributes>
</entity>
我使用spring数据jpa来获取数据。
@Query("select p from person p left join fetch p.group")
List<Person> getAll();
问题是,当我选择人员列表时,getAll函数生成1个查询以选择所有人和n查询以获取所有Person by group_id。 这是getAll()函数生成的日志:
SELECT t1.ID,t1.activity,t1.last_name,t1.matricule,t0.NAME,t0.parent_id FROM PERSON t1 LEFT OUTER JOIN GROUP_OF_PERSONS t0 ON(t0.ID = t1.group_id)
Thread(Thread [main,5,main]) - SELECT ID,employ_date,first_name,gender,last_name,matricule,phone_number,title,group_id FROM PERSON WHERE(group_id =?) bind =&gt; [5302]
Thread(Thread [main,5,main]) - SELECT ID,employ_date,first_name,gender,last_name,matricule,phone_number,title,group_id FROM PERSON WHERE(group_id =?) bind =&gt; [6965]
Thread(Thread [main,5,main]) - SELECT ID,employ_date,first_name,gender,last_name,matricule,phone_number,title,group_id FROM PERSON WHERE(group_id =?) bind =&gt; [6980]
Thread(Thread [main,5,main]) - SELECT ID,employ_date,first_name,gender,last_name,matricule,phone_number,title,group_id FROM PERSON WHERE(group_id =?)
答案 0 :(得分:1)
问题出在您的Person-&gt; Group关系上。它被标记为渴望并且没有任何提取选项,强制为从初始查询读入的每个Person单独查询。如上所述,将查询标记为使用加入或批量提取,或者使用与Group-&gt; Person关系相同或类似的OUTER选项将所有选项全部提取到单个查询中。
更好的是,除非你真的需要在应用程序的每个部分中获取关系,否则请保持懒惰。
答案 1 :(得分:0)
您在查询中使用了抓取功能(包括父级Person实体的&#39; group&#39;子元素)。这是预期的行为,因此您将遇到常见的N + 1 SQL SELECT问题。但是,由于您使用EclipseLink作为JPA提供程序,因此可以执行优化,例如使用@JoinFetch
,@BatchFetch
注释(仅适用于EclipseLink)。
查看此link或参阅EclipseLink文档了解更多信息。