반응형
지연 로딩
Member와 Team이 연관 관계를 맺고 있다고 할 때, Member를 조회하면 Team도 함께 조회된다.
단순히 Member 정보만 필요할 경우 Member를 조회할 때 Team도 함께 조회해야 할까?
이것을 해결할 수 있는 것이 '지연 로딩'이고, 지연 로딩 LAZY를 사용해서 프록시로 조회하는 방법으로 해결한다. 다음과 같이 지연 로딩을 적용할 수 있다.
로딩되는 시점에 Lazy 로딩 설정이 되어있는 Team 엔티티는 프록시 객체로 가져온다.
나중에 실제 team 객체를 사용하는 시점에 초기화가 되고, DB에 쿼리가 나간다.
- getTeam()으로 Team을 조회하면 프록시 객체가 조회가 된다.
- getTeam().getXXX()으로 Team의 필드에 접근 할 때, 쿼리가 나간다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY) // 지연 로딩
@JoinColumn(name = "TEAM_ID")
private Team team;
..
}
즉시 로딩
하지만, Member와 Team을 자주 함께 사용한다면? 지연 로딩을 사용하면 쿼리가 2번 나가기 때문에 비효율적이다.
이것을 해결할 수 있는 것이 '즉시 로딩'이고, 즉시 로딩 EAGER을 사용해서 한 번에 조회할 수 있다. 다음과 같이 즉시 로딩을 적용할 수 있다.
로딩되는 시점에 EAGER 로딩 설정이 되어있는 Team 엔티티는 실제 객체로 가져온다.
- getTeam()으로 Team을 조회하면 실제 객체가 조회가 된다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER) // 즉시 로딩
@JoinColumn(name = "TEAM_ID")
private Team team;
..
}
주의할 점
실무에서 가급적 지연 로딩만 사용하는 것이 좋다!
즉시 로딩을 적용하면 예상하지 못한 SQL이 발생할 수 있다. 그리고 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
- @ManyToOne, @OneToOne은 기본이 즉시 로딩이므로 LAZY로 설정이 필요하다.
- @OneToMany, @ManyToMany는 기본이 지연 로딩이다.
반응형
'Back-end > Spring' 카테고리의 다른 글
[SpringBoot] 페치 조인 (Fetch Join) (0) | 2022.04.06 |
---|---|
[SpringBoot] 엔티티 매핑, 연관관계 매핑 (0) | 2022.02.06 |
[Spring] 영속성 컨텍스트 (0) | 2022.01.26 |
[SpringBoot] 컴포넌트 스캔과 의존관계 자동 주입 (@Component, @Autowired, @RequiredArgsConstructor) (0) | 2022.01.16 |
SOLID 적용하여 리팩토링하기 (0) | 2022.01.10 |