Spring/Spring Boot

[Spring] JPA 즉시 로딩과 지연 로딩

민돌v 2022. 3. 23. 15:17

 

 

JPA는 데이터를 조회할 때, `FetchType` 으로 `즉시로딩(Eager)` 과 `지연로딩(Lazy)`가 있습니다.

참고로 JPA FetcyType의 default값@xxToOne에서는 EAGER, @xxToMany에서는 LAZY입니다.

 

Feth Type이란 


이 FetchType이란, JPA가 하나의 Entity를 조회할 때, 연관관계에있는 객체들을 어떻게 가져올 것이냐를 나타내는 설정값 입니다.

  • JPA는 ORM기술로, 사용자가 직접 쿼리를 생성하지 않고, JPA에서 JPQL을 이용하여 쿼리문을 생성하기 때문에, 
  • 객체와 필드를 보고 쿼리를 생성합니다. 
  • 따라서 다른 객체와 연관관계 매핑이 되어있으면 그 객체들 까지 조회하게 되는데, 이때 이 객체를 어떻게 불러올 것인가를 설정할 수 있습니다.

 

 

즉시로딩 (Eager)


즉시로딩이란, 데이터를 조회할 때, 연관된 모든 객체의 데이터까지한번에 불러오는 것 입니다.

(예시)

  • @xxToxx(fetch = fetchType.EAGER)
  • 다음과 같이 Member 엔티티와 Team 엔티티가 N:1 매핑으로 관계를 맺고 있습니다.
@Entity
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;

    @ManyToOne(fetch = FetchType.EAGER) //Team을 조회할 때 즉시로딩을 사용하곘다!
    @JoinColumn(name = "team_id")
    Team team;
}

@Entity
public class Team {

    @Id @GeneratedValue
    private Long id;
    private String teamname;
}

JPQL로 Member 1건 조회

Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();

실제 SQL 코드

//멤버를 조회하는 쿼리
select
    member0_.id as id1_0_,
    member0_.team_id as team_id3_0_,
    member0_.username as username2_0_ 
from
    Member member0_

//팀을 조회하는 쿼리
select
    team0_.id as id1_3_0_,
    team0_.name as name2_3_0_ 
from
    Team team0_ 
where
    team0_.id=?

다음과 같이 즉시 로딩(EAGER) 방식을 사용하면 Member를 조회하는 시점에 바로 Team까지 불러오는 쿼리를 날려 한꺼번에 데이터를 불러오는 것을 볼 수 있습니다.




 

지연로딩(Lazy)


지연로딩이란, 필요한 시점에 연관된 객체의 데이터를 불러오는 것 입니다.

  • @xxToxx(fetch = fetchType.LAZY)
  • 위의 예제에서 FetchType만 Lazy로 바꿔서 실행해 보겠습니다.

 

 @ManyToOne(fetch = FetchType.LAZY) //Team을 조회할 때 지연로딩을 사용하곘다!

JPQL로 Member조회

Member findMember = em.createQuery("select m from Member m", Member.class).getSingleResult();

실제 SQL 코드

//Team을 조회하는 쿼리가 나가지 않음!
select
    member0_.id as id1_0_,
    member0_.team_id as team_id3_0_,
    member0_.username as username2_0_ 
from
    Member member0_

 

결론!


즉시로딩 시, member를 조회해도, 연관된 객체인 Team까지 조회하는 쿼리문이 생성되었지만,

지연로딩 시, 연관된 객체는 지금 필요하지 않기때문에 member만 조회하는 쿼리로 생성이 됩니다.

 

Member와 연관된 Team 객체가 1개가 아닌 N개라면,

즉시로딩 시, Memeber 1개를 조회할 때, 필요하지않은, Team 객체를 조회하는 쿼리 N개가 생성되게 됩니다.

 

따라서, 가급적 지연로딩을 권장한다고 합니다!

 

 

 

 

 

 


*참고

지연로딩과 즉시로딩 : https://developer-hm.tistory.com/37

fetcyType : http://jaynewho.com/post/39