JPA Hibernate查询n+1问题,关联实体查询加载慢优化

项目场景:

提示:在使用JPA列表查询查询,明细表关联主表信息,这时查询异常慢需要20s+接口才能返回
例如:学生表关联班级表,多个学生关联一个班级. 在对学生表列表查询并关联查询班级表时,JPA查询发送了n+1条查询语句(n为数据条数)


问题描述:

这里加入伪代码:

/**
 * 班级表
 **/
 @Entity
 @Table(name="student_class")
class StudentClass{
	/**
	 * 班级名称
	 **/
	 private String className;
}
/**
 * 学生表
 **/
 @Entity
 @Table(name="student")
class Student{
	/**
	 * 学生名称
	 **/
	 private String studentName;
	
	/**
	 * 学生所属班级
	 **/ 
	 @MantyToOne
	 @JoinColumn(name="student_class_id")
	 private StudentClass studentClass;
}

在调用StudentRepository.findAll()方法时查询缓慢:

class StudentRepository{

	List<Student> findAll();
	
}

原因分析:

看控制台的SQL信息;

  1. 第一条查询student表的sql
  2. 针对每一条student数据,发送了查询student_class表的SQL
  3. 这样就对数据库进行了N+1次查询
我想原因就在这里,在sql查询中建立连接进行查询是非常耗时的

解决方案:

使用@NamedEntityGraph注解让数据一次加载完毕,减少查询次数
在Student类中加入注解

/**
 * 学生表
 **/
 @Entity
 @Table(name="student")
 @NamedEntityGraph(name = "Student.Graph", attributeNodes = {
        @NamedAttributeNode(value = "studentClass")
class Student{
	/**
	 * 学生名称
	 **/
	 private String studentName;
	
	/**
	 * 学生所属班级
	 **/ 
	 @MantyToOne
	 @JoinColumn(name="student_class_id")
	 private StudentClass studentClass;
}

修改StudentRepository的findAll方法

class StudentRepository{

	@EntityGraph(value="Student.Graph", type = EntityGraph.EntityGraphType.FETCH)
	List<Student> findAll();
	
}

这样改造后,控制台只发送了一条SQL语句:
优化前: >20s
优化后: <3s

你可能感兴趣的:(JPA,java,jpa,hibernate,mysql优化)