출처 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
💡 가급적 묵시적 조인 대신에 명시적 조인 사용
💡 가급적 JPQL이랑 SQL이랑 맞춰서 해라
⭐⭐⭐ 실무에서 정말정말 중요함 ⭐⭐⭐
-> 즉시로딩해서 가져올 때랑 똑같다.
ex) ⭐
-> 이 경우 예제...
Team teamA = new Team();
teamA.setName("teamA");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("teamB");
em.persist(teamB);
Member member1 = new Member();
member1.setUsername("member1");
member1.setTeam(teamA);
em.persist(member1);
Member member2 = new Member();
member2.setUsername("member2");
member2.setTeam(teamA);
em.persist(member2);
Member member3 = new Member();
member3.setUsername("member3");
member3.setTeam(teamB);
em.persist(member3);
em.flush();
em.clear();
String query = "select m from Member m";
List<Member> members = em.createQuery(query, Member.class)
.getResultList();
for (Member member : members) {
System.out.println("member = " + member.getUsername() + ", " + member.getTeam().getName());
// member1, teamA : SQL 날림
// member2, teamA : 1차 캐시 (SQL 날린 거 저장된 거에서 가져옴)
// member3, teamB : SQL 날림
// 회원 100명 -> N + 1
// 회원 조회를 위한 쿼리를 '한번' 날리면, 100번(N번) 돈다.
// 즉시로딩이든 지연로딩이든 다 발생함
// 따라서 fetch join으로 해결해야 함
// (select m from Member m join fetch m.team)
}
tx.commit();
fetch join을 하지 않은 경우 : select m from Member m
-> 쿼리 3번 나감 (memberA와 memberB의 팀이 같기 때문)
-> 만약 각 member들이 팀이 다 다르다면? 엄청난 쿼리 날림
fetch join을 한 경우 : select m from Member m join fetch m.team
ex) ⭐
-> 이 경우 예제...
Team teamA = new Team();
teamA.setName("teamA");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("teamB");
em.persist(teamB);
Member member1 = new Member();
member1.setUsername("member1");
member1.setTeam(teamA);
em.persist(member1);
Member member2 = new Member();
member2.setUsername("member2");
member2.setTeam(teamA);
em.persist(member2);
Member member3 = new Member();
member3.setUsername("member3");
member3.setTeam(teamB);
em.persist(member3);
em.flush();
em.clear();
String query = "select t from Team t join fetch t.members";
List<Team> teams = em.createQuery(query, Team.class)
.getResultList();
for (Team team : teams) {
System.out.println("team = " + team.getName() + " | members = " + team.getMembers().size());
}
tx.commit();
-> 데이터 뻥튀기 : teamA 입장에서는 한 개인데, 멤버가 2명이라 2 row가 됨