250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 낙관적락
- 연관관계
- 지연로딩
- 즉시로딩
- 일대다
- BOJ
- JPQL
- 비관적락
- 연결리스트
- querydsl
- eager
- 데코레이터
- shared lock
- PS
- 동적sql
- 다대다
- fetch
- dfs
- CHECK OPTION
- 유니크제약조건
- execute
- SQL프로그래밍
- 스토어드 프로시저
- 이진탐색
- 힙
- FetchType
- 스프링 폼
- 다대일
- 백트래킹
- exclusive lock
Archives
- Today
- Total
흰 스타렉스에서 내가 내리지
프록시와 즉시로딩/지연로딩 본문
728x90
# 프록시
# 1
Member member = memberRepository.findById(1L).or(...);
System.out.println(member.getTeam());
# 2
Member member = memberRepository.findById(1L).or(...);
System.out.println(member.getUsername());
# 1 에서는, 회원은 물론이고, 회원과 연관된 팀의 이름도 출력한다.
# 2 에서는, 회원 엔티티만 사용하고 팀 엔티티는 전혀 사용하지 않는다.
# 2에서 회원 엔티티만 사용하므로, 그와 연관된 팀 엔티티까지 DB 에서 함께 조회해 두는 것은 비효율적이다.
JPA 는 실제 사용될 때까지 데이터베이스 조회를 지연하는 방법을 제공하는데, 이것을 지연 로딩이라 한다.
지연 로딩을 사용하려면, 실제 엔티티 객체 대신에 데이터베이스 조회를 지연할 수 있는 가짜 객체가 피룡한데, 이것을 프록시 객체라 한다.
# 프록시 기초
- 엔티티를 실제 사용하는 시점까지 데이터베이스 조회를 미루고 싶으면 getReferenceById() 를 사용한다.
- 이 메소드를 호출할 때, JPA 는 DB 를 조회하지 않고, DB 접근을 위임한 프록시 객체를 반환한다.
* 프록시 특징
- 프록시 클래스는 실제 클래스를 상속 받아서 만들어진다.
- 프록시 객체는 실제 객체에 대한 참조 (target)를 보관한다.
- 그리고 프록시 객체의 메소드를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.
- 프록시 객체는 처음 사용할 떄 한 번만 초기화 된다.
- 프록시 객체를 초기화한다고 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 프록시 객체가 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근할 수 있다.
-- 프록시 클래스 예상 코드
class MemberProxy extends Member {
Member target = null;
public String getName(){
if (target == null) {
// 2. 초기화 요청
// 3. DB 조회
// 4. 실제 엔티티 생성 및 참조 보관
this.target = ...;
}
// 5. target.getName();
return target.getName();
}
}
# 프록시와 식별자
- 엔티티를 프록시로 조회할 떄, 식별자(PK) 값을 파라미터로 전달하는데 프록시 객체는 이 식별자 값을 보관한다.
- 프록시 객체는 식별자 값을 가지고 있으므로 식별자 값을 조회하는 team.getId() 를 호출해도 프록시를 초기화하지 않는다.
- 연관관계를 설정할 떄는 식별자 값만 사용하므로 프록시를 사용하면 데이터베이스 접근 횟수를 줄일 수 있다.
# 즉시로딩과 지연로딩
- 프록시 객체는 주로 연관된 엔티티를 지연 로딩할 떄 사용한다.
# 즉시 로딩
- 엔티티를 조회할 떄 연관된 엔티티도 함께 조회한다.
- @ManyToOne(fetch = FetchType.EAGER)
# 지연 로딩
- 연관된 엔티티를 실제 사용할 때 조회한다.
- @ManyToOne(fetch = FetchType.LAZY)
# JPA 기본 페치 전략
- @ManyToOne, @OneToOne: 즉시 로딩 (FetchType.EAGER)
- @OneToMany, @ManyToMany: 지연 로딩 (FetchType.LAZY)
연관된 엔티티가 하나면 즉시 로딩을, 컬렉션이면 지연 로딩을 사용한다.
컬렉션을 로딩하는 것은 비용이 많이 들고 잘못하면 너무 많은 데이터를 로딩할 수 있기 때문이다.
일단 모든 연관관계에 지연로딩을 사용하는 것이 좋다.
그리고 애플리케이션 개발이 어느 정도 완료단계에 왔을 때 실제 사용하는 상황을 보고 꼭 필요한 곳에만 즉시 로딩을 사용하도록 최적화하면 된다.
'JPA' 카테고리의 다른 글
TypeQuery 와 Query (0) | 2024.04.13 |
---|---|
고아 객체 (0) | 2024.04.10 |
일대일 식별 관계 (0) | 2024.04.04 |
복합 키 : 비식별 관계 매핑 (1) | 2024.04.04 |
식별 관계 vs 비식별 관계 (0) | 2024.04.04 |