일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- @Bean
- open-in-view
- 스프링 빈
- Open EntityManager In View
- 생성자 주입
- open session in view
- mavenCentral
- 불변 객체
- View Resolver
- Request flow
- Batch
- 참조 타입
- Handler Adepter
- @componentScan
- @FunctionalInterface
- 익명 함수
- Spring Batch
- @Configuration
- 필드 주입
- 빈
- 메서드 주입
- Spring Framework
- 이펙티브 자바
- 일괄처리
- 가변 객체
- 싱글 스레드
- 컴포넌트스캔
- Dispatcher Servlet
- spring boot
- OSIV
- Today
- Total
보다 더 나은 내일의 나를 위해
즉시로딩(EAGER)과 지연로딩(LAZY) 본문
JPA에서는 객체를 DB에서 찾아올 때의 방식을 위한 즉시 로딩과 지연 로딩 옵션 중 하나를 설정해 줄 수 있습니다.
@ManyToOne의 기본값은 즉시 로딩이고, @ManyToMany의 기본값은 지연 로딩으로 되어있습니다.
이 두 옵션은 무슨 차이가 있을까요?
즉시 로딩 : 즉시 로딩은 DB에서 엔티티를 찾아올 때 연관관계를 맺고 있는 엔티티들을 한 번에 바로 조회합니다.
지연 로딩 : 지연 로딩은 DB에서 엔티티를 찾아올 때 연관관계를 맺고 있는 엔티티들은 프록시 객체를 할당해 주어 나중에 실제로 사용할 때 따로 조회를 시도합니다.
코드를 통해 한번 알아봅시다.
우선 사용할 엔티티 구조입니다.
Human과 Organism은 서로 1 : N 관계입니다. 이때 fetch의 기본 값은 즉시 로딩(EAGER)으로 설정되어 있습니다.
Human
@Entity
public class Human {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "human_id")
private Long id;
@Column
private String name;
@ManyToOne(fetch = FetchType./* 로딩 설정 */)
@JoinComumn(name = "organism_id")
private Organism organism;
... Getter
}
Organism
@Entity
public class Organism {
@Id @GeneratedValue(strategy = GeneratioinType.AUTO)
@Column(name = "organism_id")
private Long id;
@Column
private String kind;
@Column
private String name;
@OneToMany(mappedBy = "organism")
private List<Human> humans = new ArrayList<>();
... Getter
}
또한 테스트를 위한 함수도 만들어봅시다.
테스트용
@Transactional(readOnly = true)
public void findHuman(Long id) {
Human human = humanRepository.findById(id).orElseThrow);
System.out.println("찾아옴");
System.out.println(human);
System.out.println(human.getOrganism());
}
마지막으로 sql을 보기 위해 application 파일을 설정해줍니다.
application.properties
# DB 설정
spring.jpa.properties.hibernateformat_sql=true
application.yaml
spring:
DB 설정
jpa:
prperties:
hibernate:
format_sql: true
즉시 로딩(EAGER)
우선 즉시 로딩의 동작 방식을 알아봅시다.
select
human0_.idx as idx1_0_0_,
human0_.name as name2_0_0_,
human0_.organism_id as organism3_0_0_,
organism1_.idx as idx1_1_1_,
organism1_.kind as kind2_1_1_,
organism1_.name as name3_1_1_
from
human human0_
left outer join
organism organism1_
on human0_.organism_id=organism1_.idx
where
human0_.idx=?
찾아옴
Human@658098a2
Organism@2190508d
이처럼 Human을 조회할 때 Organism까지 한번에 조회합니다.
지연로딩(LAZY)
지연 로딩일때는 어떻게 동작할까요?
한번 실행시켜봅시다.
select
human0_.idx as idx1_0_0_,
human0_.name as name2_0_0_,
human0_.organism_id as organism3_0_0_
from
human human0_
where
human0_.idx=?
찾아옴
Human@50628080
select
organism0_.idx as idx1_1_0_,
organism0_.kind as kind2_1_0_,
organism0_.name as name3_1_0_
from
organism organism0_
where
organism0_.idx=?
Organism@7167d81b
지연 로딩으로 설정하면 처음엔 우선 Human만 조회합니다.
이때 Human과 연관관계를 맺고 있는 Organism은 프록시 객체가 들어가 있습니다.
이후에 Organism을 조회하려고 할 때 DB에서 조회해 객체를 보여주게 됩니다.
'spring > jpa' 카테고리의 다른 글
JPA의 Open-In-View란? (0) | 2022.04.26 |
---|