[JPA] 즉시로딩과 지연로딩이란? (FetchType.EAGER, FetchType.LAZY)
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()로 엔티티를 호출할 때 엔티티를 조회한다.
#정리.....
게시판 목록에서 작성자를 표시해야한다. > 즉시로딩
게시판 목록에서 댓글을 미표시한다. > 지연로딩
게시판 상세조회시 작성자를 표시해야한다. > 즉시로딩
게시판 상세조회시 댓글을 표시한다. > 즉시로딩