如何避免JPA中为每行数据发起单独数据库调用?
解决JPA N+1查询问题,合并单次调用获取所有数据
你遇到的是典型的N+1查询问题:主查询只获取了BarBar的基础数据,但构造FooDTO时访问了BarBar关联的Foo实体属性(比如bar.abc是关联到Foo的懒加载属性),Hibernate为了获取每行对应的Foo数据,会发起单独的查询。
以下是两种解决方法:
方法一:用JOIN FETCH提前加载关联实体
如果BarBar和Foo是关联关系(比如@ManyToOne Foo abc;),修改查询语句,通过JOIN FETCH一次性加载关联的Foo数据,避免懒加载触发:
@Query( """ SELECT new com.foo.dto.Foo( bar.id, bar.test, foo)\ FROM BarBar bar JOIN FETCH bar.abc foo WHERE bar.test in :test\ """) List<Foo> getFoosById(List<Long> test);
这样主查询会通过JOIN语句把BarBar和对应的Foo数据一次性查出来,不会再发起后续的单独查询。
方法二:直接查询DTO需要的字段(无需加载整个实体)
如果不需要完整的Foo实体,只需要其中部分字段,可以直接在构造DTO时指定这些字段,避免加载整个实体:
@Query( """ SELECT new com.foo.dto.Foo( bar.id, bar.test, bar.abc.id, bar.abc.name)\ FROM BarBar bar WHERE bar.test in :test\ """) List<Foo> getFoosById(List<Long> test);
注意要确保FooDTO有对应参数的构造方法,Hibernate会直接从JOIN结果中提取需要的字段,无需单独查询Foo。
额外提示:尽量避免全局设置关联为FetchType.EAGER(急加载),这会影响其他查询的性能,推荐在需要的查询中通过JOIN FETCH按需加载关联数据。
内容的提问来源于stack exchange,提问作者Jett
相关产品推荐
相关产品推荐

