본문 바로가기

👩‍💻 BackEnd/🍃 스프링부트 [SpringBoot]

[JPA] 양방향 매핑

업로드 파일을 프로젝트 외부에 두는 이유 

 

프로젝트 폴더에는 .java 파일이 있음. 

 

이 파일이 컴파일 되어 실행이되는 것임. 

 

target 폴더가 있는데 그 안에 서버가 실행될 때 컴파일을 해서 .class 파일이 여기에 저장됨. 

 

프로젝트 폴더 안에 있는 파일들은 모두 컴파일해서 target 폴더에 반영이된다.  -> 이 과정을 "Deploy(배포하다)" 라고 한다. 

 

그래서 결국 target 에 있는 파일들이 실행이 되는 것임. 

 

만약에 프로젝트 내부에 업로드 폴더를 만든 뒤 이미지를 업로드하면, target 폴더로 이동하게 된다. 

target 폴더 내부에 있는 파일들이 실행이 된다. 

 

배포될 때 즉, target 파일들로 옮겨지는데 시간이 걸리는데 이미지 파일의 경우 용량이 조금 더 커서 시간이 오래 걸릴 수 있다. 

이때 걸리는 시간이 프로그램이 실행되는 시간보다 더 길 수 있다. Deploy 시간 > 프로그램 실행시간 -- 엑박이 뜰 수 있음. 

 

그렇다면 사진을 프로젝트 내부가 아닌 외부 폴더에 저장을 하게 될 경우 이러한 시간차로 인한 문제를 해결할 수 있다. 

 

정리 

  • 프로젝트 내부에 둘 경우, 이미지를 업로드하고 배포가되는 시간보다 페이지 이동 시간이 더 짧게 걸린다. 

--- 

프로필 페이지로 이동할 때

  • 사용자의 정보
  • 이미지 정보
  • 구독 정보 등

을 가지고 이동을 해야한다. 

여러개의 정보를 가지고 와야한다. 

 

JPA 영속성 컨테이너 

 

db에 user 정보가 있을텐데 

user 를 select 할 때 user의 이미지 정보를 같이 들고와서 영속화가 될 수 있도록 할 것이다. 

 

LAZY 전략일 경우 Select 쿼리 하나만 날아감. 
// 연관관계의 주인이 아니므로 테이블에 컬럼 생성하지 않도록 설정
// User 를 Select 할 때 해당 User id 로 등록된 image 모두 들고오도록
// Lazy = User 를 Select 할 때 해당 User id 로 등록된 image 가져오지 않도록 - 대신 getImages()함수가 호출될 때 가져옴, 
// Eager = User 를 Select 할 때 해당 User id로 등록된 image 들을 전부 Join 해서 가져오도록
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Image> images;  // 양방향 매핑 컬럼

LAZY 전략

 

그리고 Service 클래스에서 getImages().get(0) 로 이미지를 가져오는 메서드를 호출하면 그때 이미지들을 가져온다. 

/**
 * @param userId 해당 프로필 페이지 사용자 아이디
 */
public User memberProfile(int userId) {
    // SELECT * FROM image WHERE userId =:userId;
    User userEntity = userRepository.findById(userId).orElseThrow(() -> {
        throw new CustomException("해당 프로필 페이지는 없는 페이지입니다.");
    });

    userEntity.getImages().get(0);
    log.info("=================");

    return userEntity;
}

 

날아간 쿼리를 확인해보면 Select 가 두번 일어난 것을 발견할 수 있다. (User 테이블과 Image 테이블) 

 

 

 

EAGER 전략일 경우 Select 절과 함께 Left outer Join 쿼리가 날아감. 

 

@OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
private List<Image> images;  // 양방향 매핑 컬럼

 

 

EAGER 전략