JPA

[JPA] 즉시로딩과 지연로딩이란? (FetchType.EAGER, FetchType.LAZY)

dev.mk 2023. 11. 14. 16:54
반응형

JPA에서 연관관계를 조회할 때 참조하는 객체들의 조회 시점을 선택할 수 있도록
두 가지 방법을 제공하는데 즉시 로딩(EAGER Loading)과 지연 로딩(LAZY Loading)이다.

 

각 연관관계의 default 속성
- @ManyToOne : EAGER
- @OneToOne : EAGER
- @ManyToMany : LAZY
- @OneToMany : LAZY

 

1. 즉시 로딩(EAGER)

- @ManyToOne(fetch = FetchType.EAGER)

- 엔티티를 조회할 떄 연관된 엔티티도 함께 조회한다.
- 즉시로딩을 사용하면 실제 Member 엔티티를 불러온다.
- 즉시 로딩을 최적화하기 위해 가능하면 조인쿼리를 사용한다.

 

2. 지연 로딩(LAZY)

- @ManyToOne(fetch = FetchType.LAZY)

- 연관된 엔티티를 실제 사용할 때 조회한다.
- 이때 실제 Member 객체가 아닌 프록시 Member 객체를 넣어놓는다.

- 엔티티를 호출하는 시점에 조회한다.

 

 

테스트를 해보자.

 

 

Board.java

@Table(name = "jpa_board")
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
public class Board {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "JPA_BOARD_SEQ")
    @Column(name="bno")
    private int bno;	//게시판(PK)
    @Column(name="title", columnDefinition = "varchar(100)")
    private String title;
    @Column(name="content", columnDefinition = "varchar(255)")
    private String content;
    @CreationTimestamp
    @Column(name="reg_date")
    @Temporal(TemporalType.DATE) // 포맷 yyyy-MM-dd		
    private Date regDate;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="mno")
    private Member member;
}

 

Member.java

@Table(name = "jpa_member")
@Entity
@Data
@NoArgsConstructor
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "JPA_MEMBER_SEQ")
    @Column(name="MNO")
    private int mno;	//회원(PK)
    @Column(name="NAME", columnDefinition = "varchar(100)")
    private String name;
    @Column(name="AGE", columnDefinition = "number(10)")	
    private Integer age;
    @Column(name="REG_DATE")
    @Temporal(TemporalType.DATE) // DATE + TIME : 날짜 및 시간
    private Date regDate;
}

 

 

컨트롤러에서 서비스를 호출하여 테스트를 진행

Controller.java

Board result = testService.getFindById(1);
log.info("=============================");
log.info("{}",result.getMember());

 

 

1. 즉시로딩 실행

@ManyToOne(fetch = FetchType.EAGER)

 

console

    select
        board0_.bno as bno1_0_0_,
        board0_.content as content2_0_0_,
        board0_.mno as mno5_0_0_,
        board0_.reg_date as reg_date3_0_0_,
        board0_.title as title4_0_0_,
        member1_.mno as mno1_2_1_,
        member1_.age as age2_2_1_,
        member1_.name as name3_2_1_,
        member1_.reg_date as reg_date4_2_1_       
    from
        jpa_board board0_       
    left outer join
        jpa_member member1_               
            on board0_.mno=member1_.mno       
    where
        board0_.bno=1
=============================
Member(mno=1, name=테스터, age=10, regDate=2023-11-10)

 

조인을이용하여 엔티티 모두를 조회한다.

 

 

1. 지연로딩 실행

@ManyToOne(fetch = FetchType.LAZY)

    select
        board0_.bno as bno1_0_0_,
        board0_.content as content2_0_0_,
        board0_.mno as mno5_0_0_,
        board0_.reg_date as reg_date3_0_0_,
        board0_.title as title4_0_0_       
    from
        jpa_board board0_       
    where
        board0_.bno=1
=============================
    select
        member0_.mno as mno1_2_0_,
        member0_.age as age2_2_0_,
        member0_.name as name3_2_0_,
        member0_.reg_date as reg_date4_2_0_ 
    from
        jpa_member member0_ 
    where
        member0_.mno=?
Member(mno=1, name=테스터, age=10, regDate=2023-11-10)

 

처음 게시판만 조회하고 getMember()로 엔티티를 호출할 때 엔티티를 조회한다.

 

#정리.....

게시판 목록에서 작성자를 표시해야한다. > 즉시로딩

게시판 목록에서 댓글을 미표시한다. > 지연로딩

게시판 상세조회시 작성자를 표시해야한다. > 즉시로딩

게시판 상세조회시 댓글을 표시한다. > 즉시로딩

반응형