java面試之n+1問題


在一對多或者多對多的時候。如果通過一的一方取獲得多的一方的數據。除了第一次查詢表的數據以外。每獲得一條多的一方的數據就查詢一次。

如:通過學生表的記錄查詢成績表的記錄。

一個學生就查詢一次,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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM