解决 SpringData JPA 的n+1问题
1. 首先解决 n+1 问题
(1)Entity 添加 @NamedEntityGraph
1 @Entity 2 @Table(name = "tb_depart_detail", schema = "") 3 @NamedEntityGraph(name = "depart_detail.Graph", attributeNodes = { 4 @NamedAttributeNode(value = "depart") 5 }) 6 @SuppressWarnings("serial") 7 public class DepartDetailEntity implements java.io.Serializable { 8 @ManyToOne(fetch = FetchType.EAGER) 9 @JoinColumn(name = "depart_id") 10 public DepartEntity getDepart() { 11 return depart; 12 } 13 14 public void setDepart(DepartEntity depart) { 15 this.depart = depart; 16 } 17 }
(2) 重写 JpaRepository 的API 指定使用 NameEntityGraph
1 import com.doctor.assistant.userserver.springdata.entity.DepartDetailEntity; 2 import org.springframework.data.jpa.repository.EntityGraph; 3 import org.springframework.data.jpa.repository.JpaRepository; 4 5 import java.util.List; 6 7 public interface DepartDetailRepository extends JpaRepository<DepartDetailEntity, String> { 8 9 @Override 10 @EntityGraph(value = "depart_detail.Graph",type = EntityGraph.EntityGraphType.FETCH) 11 List<DepartDetailEntity> findAll(); 12 }
(3) Test 测试 :
2. 三层及更多关联时,解决 n+1 的方式:
1 @Entity 2 @Table(name = "t_base") 3 @Inheritance(strategy = InheritanceType.JOINED) 4 @NamedEntityGraph(name = "base.Graph", attributeNodes = { 5 @NamedAttributeNode(value = "someList"), 6 @NamedAttributeNode(value = "userList", subgraph = "outterGraph") 7 } 8 ,subgraphs = { 9 @NamedSubgraph(name = "outterGraph",attributeNodes = { 10 @NamedAttributeNode(value = "outterList",subgraph = "innerGraph") 11 }),@NamedSubgraph(name = "innerGraph",attributeNodes = { 12 @NamedAttributeNode("innerList") 13 }) 14 })
3. 若想保留原接口,再写一个 Repository的实现类,其中什么也不做,即可保留原方法:
1 @Repository 2 public interface EAGERUserRepository extends JpaRepository<TSBaseUser, String> { 3 }