Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
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 more
Archives
Today
Total
관리 메뉴

요리사에서 IT개발자로

스파르타 부트캠프 Spring Master 3강 지연로딩과 즉시로딩 본문

Spring

스파르타 부트캠프 Spring Master 3강 지연로딩과 즉시로딩

H.S-Backend 2024. 5. 29. 16:25

 

음식테이블과 고객 테이블이 N: 1양방향 관계일 때

@Test
@DisplayName("아보카도 피자 조회")
void test1() {
    Food food = foodRepository.findById(2L).orElseThrow(NullPointerException::new);

    System.out.println("food.getName() = " + food.getName());
    System.out.println("food.getPrice() = " + food.getPrice());

    System.out.println("아보카도 피자를 주문한 회원 정보 조회");
    System.out.println("food.getUser().getName() = " + food.getUser().getName());
}

 

아보카도 피자 의 가격을 조회하려고만 했는데

자동으로 JONIN문을 사용하여

연관관계가 설정되어있는 고객테이블 정보도 가져오고있다.

 

JPA는 연관관계가 설정된

Entity정보를 바로 가져올지, 필요할 때 가져올지 설정할 수 있다.

 

가져오는 방법은 JPA에서 Fetch Type이라한다.

 

Fetch Type 종류

 

LAZY(지연로딩)

필요한 시점에 정보를 가져온다.

EAGER(즉시로딩) 

조회할 때 연관된 모든 Entity정보를 즉시 가져온다.

 


 

@OneToMany

Fetch Type의  default

LAZY(지연로딩)


@ManyToOne은

Fetch Type의 default

EAGER(즉시로딩)

 

애너테이션 이름 뒤쪽에 Many가 붙어있으면 설정된 해당 필드가 Java컬렉션 타입일것이다.

해당 Entity정보가 여러개 들어있을 수 있다는 것을 의미한다.

효율적으로 정보를 조회하기 위해 default가 LAZY(지연로딩)이다.

 

반대로 이름 뒤쪽이 One일 경우

Entity정보가 한개만 들어오기때문에

즉시 로딩(EAGER)을 해도 문제가 없어서 default로 되어있다.

 

@Test
@Transactional
@DisplayName("Robbie 고객 조회")
void test2() {
    User user = userRepository.findByName("Robbie");
    System.out.println("user.getName() = " + user.getName());

    System.out.println("Robbie가 주문한 음식 이름 조회");
    for (Food food : user.getFoodList()) {
        System.out.println(food.getName());
    }
}

Robbie 고객을 조회한 후 Robbie 고객이 주문한 음식들의 이름을 조회했는데

 

@OneToMany의 default가 LAZY(지연로딩) 으로 설정되어있어

user.getName()으로  고객을 조회

@OneToMany(mappedBy = "user")
private List<Food> foodList = new ArrayList<>();

 

for문으로 food : user.getFoodList를 사용하여

for (Food food : user.getFoodList()) {
    System.out.println(food.getName());
}

고객이 주문한 음식의 정보가 필요한 시점

음식 테이블에 해당 고객Entity의 식별자 값(Id)을 사용하여 

food.getName() == Robbie가

주문한 음식 내용들을 출력을한다.


영속성 컨텍스트와 지연로딩

 

영속성 컨텍스트의 기능 

1차캐시

쓰기지연저장소

변경감지

 

지연로딩(LAZY)도 마찬가지로 영속성 컨텍스트 기능중의 하나이기에

영속성 컨텍스트가 존재해야한다 == 트랜잭션이 적용되어있어야한다.

 

한마디로 쓰기지연저장소에 해당 DB가 머무르고 있어야한다.

@Test
@Transactional
@DisplayName("Robbie 고객 조회")
void test2() {
    User user = userRepository.findByName("Robbie");
    System.out.println("user.getName() = " + user.getName());

    System.out.println("Robbie가 주문한 음식 이름 조회");
    for (Food food : user.getFoodList()) {
        System.out.println(food.getName());
    }
}

 

@Test
@DisplayName("Robbie 고객 조회 실패")
void test3() {
    User user = userRepository.findByName("Robbie");
    System.out.println("user.getName() = " + user.getName());

    System.out.println("Robbie가 주문한 음식 이름 조회");
    for (Food food : user.getFoodList()) {
        System.out.println(food.getName());
    }
}

조회 실패테스트 코드에

@Transaction 에너테이션이 설정되어있지않아서 실패한것

 

영속성 컨텍스트의 기능인

쓰기지연저장소에 호출한 Robbie 가

머물러있지않아서

getName()도 출력할 수 없다는것이다.

 

@Transaction의 활용

https://hs-backend.tistory.com/127

 

스파르타 부트캠프 Spring Master 2강 영속성 컨텍스트 기능

영속성 컨텍스트는 Entity객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간https://hs-backend.tistory.com/126 스파르타 부트캠프 Spring Master 2강 영속성 컨텍스트영속성 컨텍스트란 지속성을 의미한

hs-backend.tistory.com

반응형