JAVA

즉시로딩(Eager)과 지연로딩(Lazy)

즉시로딩(Eager)과 지연로딩(Lazy)

예제로 이해하기

 데이터베이스의 사용자 테이블(User)
id username password email
1 ssar 1234 ssar@nate.com
2 sai 1234 sai@naver.com
데이터베이스의 게시글 테이블(Board)
id title content userId
1 제목1 내용1 1
2 제목2 내용2 2
3 제목3 내용3 2
영속성 컨텍스트에 저장된 게시글 객체
public class Board {
	
	private int id; 
	private String title;
	private String content;
	private User user; 
	
}

 

데이터베이스의 데이터를 가지고 게시글 모델을 만들 때 데이터베이스의 게시글 테이블과와 영속성 컨텍스트의 자바 오브젝트에 모순이 생겨 매핑 시 문제가 생긴다. 여기서 @ManyToOne 어노테이션을 걸어주면 이 문제를 해결할 수 있다. 영속성 컨텍스트는 데이터를 동기화하려고 하기 때문에 모순된 데이터(userId)가 들어오면 이를 Primary key로 인식하여 사용자 테이블에서 데이터를 조인하여 가지고 온다. 이는 @ManyToOne의 기본 전략이 Eager이기 때문인데 Lazy 전략으로 바꿔주면 모순된 데이터는 무시하고 나머지 데이터를 가지고 온다. Lazy 전략은 요청시 데이터베이스에서 데이터를 동기화해서 가져오게 된다. 즉 필요할 때 데이터를 동기화한다.

<Eager 전략>
eager
<Lazy 전략>
lazy
사용하는 방법
package com.cos.blogapp.domain.board;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.cos.blogapp.domain.user.User;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Table(name = "board")
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class Board {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id; //PK (자동증가 번호)
  
  @Column(nullable = false, length = 70)
  private String title; // 아이디
  
  @Lob
  private String content;
  
  @JoinColumn(name = "userId")
  @ManyToOne(fetch = FetchType.EAGER) 
  private User user; 
  
}
기본 전략

@ManyToOne : Eager
@OneToMany : Lazy

옵션을 추가해서 전략 지정 가능

fetch = FetchType.LAZY
fetch = FetchType.EAGER

만약 조인이 필요없는 페이지(게시글 데이터만 가져오는 경우)에서 Eager 전략을 쓰면 연산이 많이 일어나기 때문에 Lazy 전략을 쓰는 것이 좋다.

opne-in-view 설정

jpa:
  open-in-view: true
  hibernate:
    ddl-auto: none
    naming:
      physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  show-sql: true
false

트렌젝션이 종료될 때 데이터베이스 커넥션이 끊긴다. Lazy 전략은 응답하기 직전에 동기화되기 때문에 적절하지 않다.

open-in-view
true

데이터베이스 쿼리가 뷰를 렌더링하기 직전까지 데이터베이스 커넥션이 유지된다.

Lazy전략은 open-in-view 기본 설정을 true로 해야합니다.
최신글