java面试之n+1问题

2018-06-18 02:08:11来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

在一对多或者多对多的时候。如果通过一的一方取获得多的一方的数据。除了第一次查询表的数据以外。每获得一条多的一方的数据就查询一次。

如:通过学生表的记录查询成绩表的记录。

一个学生就查询一次,50个学生就查询50次。

如果需要查询50个学生的成绩,需要查询数据库的次数为 第一次查询学生的记录+50次查询成绩的记录。这个情况我们成为 N+1.

//需求:查询所有的学生,以及所有学生都有查询他的成绩

@Test

public void find(){

//1.获得学生信息

EntityManager manager = JpaUtils.getEntityManager();

TypedQuery<Student> query = manager.createQuery("select s from Student s", Student.class);

List<Student> students = query.getResultList();

for (Student student : students) {

System.out.println("学生名:"+student.getStuName());

//每个学生都有获得他的成绩

List<Result> results = student.getResults();

for (Result result : results) {

System.out.println("分数:"+result.getResScore()+",科目:"+result.getResSubject());

}

}

 

manager.close();

}

 


对于一些对性能要不高的内部系统,其实N+1问题是可以接受。但对于要求性能高的系统是不可以使用的。

解决N+1问题的方法就是通过连接表查询,在JPQL里面通过fetch 设置生成SQL语句的策略

 

 1 package cn.gzsxt.test;
 2 
 3 import java.util.List;
 4 
 5 import javax.persistence.EntityManager;
 6 import javax.persistence.EntityTransaction;
 7 import javax.persistence.TypedQuery;
 8 
 9 import org.junit.Test;
10 
11 import cn.gzsxt.entity.Result;
12 import cn.gzsxt.entity.Student;
13 import cn.gzsxt.utils.JpaUtils;
14 
15 public class StudentTest {
16     //需求:通过ID查询所有学生表的记录,同时查询该学生的对应的成绩的信息!
17     @Test
18     public void findResultByStudent(){
19         EntityManager entityManager = JpaUtils.getEntityManager();
20         TypedQuery<Student> createQuery = entityManager.createQuery("select s from Student s",Student.class);
21         List<Student> students = createQuery.getResultList();
22         for (Student student : students) {
23             System.out.println("学生名:"+student.getStuName());
24             List<Result> results = student.getResults();
25             for (Result result : results) {
26                 System.out.println(result.getResSubject()+":"+result.getResScore());
27             }
28         }
29         entityManager.close();
30     }
31     //需求:通过ID查询所有学生表的记录,同时查询该学生的对应的成绩的信息!解决n+1问题
32     @Test
33     public void findResultByStudent2(){
34         EntityManager entityManager = JpaUtils.getEntityManager();
35         TypedQuery<Student> createQuery = entityManager.createQuery("select distinct s from Student s inner join fetch s.results",Student.class);
36         List<Student> students = createQuery.getResultList();
37         for (Student student : students) {
38             System.out.println("学生名:"+student.getStuName());
39             List<Result> results = student.getResults();
40             for (Result result : results) {
41                 System.out.println(result.getResSubject()+":"+result.getResScore());
42             }
43         }
44         entityManager.close();
45     }
46 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:单点登录与权限管理本质:单点登录介绍

下一篇:spring boot 系列之三:spring boot 整合JdbcTemplate