만약, 멤버 클래스와 팀 클래스가 연관관계로 매핑되어 있다고 가정하자.
이때, 조회는 아래와 같이 3가지의 경우의 수가 있다.
- 멤버만 조회
- 팀만 조회
- 멤버와 팀 모두 조회
//1.멤버와 팀 다 가져옴.
Member member = em.find(Member.class, 1L);
//2.이때도, 멤버와 팀 다 가져옴.
Team team = em.find(Team.class, 2L);
지연 로딩 Lazy Loading
근데 만약, 멤버 혹은 팀 하나만 가져오고 싶다면? ➡️ 지연로딩 Lazy Loading을 사용하자!
//Member class
@Entity
public class Member{
...
@ManyToOne(fetch = FetchType.LAZY) // 이 부분!
@JoinColumn(name = "TEAM_ID")
private Team team;
}
//main
Member member = em.find(Member.class, 1L);
Team team = member.getTeam(); //이때는, Team 데이터를 안가져 온다. Team을 프록시 객체로 초기화
sout(member); // ➡️ Member Class의 Member 출력
sout(team.getName()); // ➡️ 이렇게 실제로 사용될 때, 프록시 내 데이터를 채운다.
즉, 지연 로딩으로 설정 시, 해당 객체는 데이터를 읽을 때가 아닌, 실제로 사용될 때, 가져온다!
➡️ Tip) 만약, 대부분의 상황에서 두 객체를 따로따로 가져와 사용하는 경우라면, Lazy Loading을 사용하자!
아래의 매핑 애너테이션들은 Lazy Loading이 Default 옵션이다. ( 헷갈리니, 그냥 직접 명시해주자...)
- @OneToMany
- @ManyToMany
즉시 로딩 Eager Loading
만약, em.find() 할 때, 동시에 둘 다 가져오고 싶다면? ➡️ 즉시 로딩!
아래의 매핑 애너테이션들은 Eager Loading이 Default 옵션이다.( 헷갈리니, 그냥 직접 명시해주자...)
- @ManyToOne
- @OneToOne
왠만하면, Lazy Loading을 사용하자!
왜? ➡️ Eager Loading(즉시 로딩)은 JPQL에서 N+1 문제를 야기한다!
왜 N+1 발생? ➡️ Eager Loading으로 해당 객체를 조회할 때, 관련된 연관 엔티티들도 동시에 같이 가져오니까!
N+1 문제
1개의 쿼리를 날렸는 데, 그 쿼리때문에 N개의 쿼리가 추가로 실행되는 문제
Tip)
- 먼저, 몽땅 Lazy Loading으로 초기화 ➡️ JPQL의 Fetch Join으로 런타임 환경에서 필요한 것들만 동시에 가져온다.
강의 출처
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21709&tab=curriculum&category=questionDetail
'JPA' 카테고리의 다른 글
[JPA] 경로 표현 (0) | 2023.05.29 |
---|---|
조건식 (case, coalesce, nullif) (0) | 2023.05.29 |
프록시 (0) | 2023.05.23 |
JPA - 연관관계 주인(feat. mappedBy) (0) | 2023.05.19 |
영속성 컨텍스트! (2) | 2023.05.11 |