fetch와 Join fetch 차이
Why?
앨범 조회 기능의 JPQL을 사용하게 되었는데, 이때 Join을 사용하면 좋을지, Fetch Join을 사용하면 좋을지 고민을 해보면 좋을것 같다는 리뷰를 받게 되었고, Fetch Join에 대해 제대로 알아보고자 작성하게 되었다.
@Query("SELECT m FROM AlbumMember m JOIN m.user u WHERE u.id = :id")
List<Album> findAllByUserId(@Param("id") Long id);
JPQL
JPA의 일부분으로 정의된 플랫폼 독립적인 객체 지향 쿼리 언어로 SQL과 다르게 엔티티 클래스를 바라보고 작성해야한다.
@Qurey 어노테이션을 활용해 작성 할 수 있다.
@Qurey 는 Entity의 JpaRepository를 상속받는 인터페이스에 정의하게 되며, 기본 작성법은 from 구문에 Entity의 객체를 선언해 해당 객체의 속성명을 통해 조건과 파라미터를 작성하면 된다.
프로젝션
- SELECT 절에 조회할 대상을 지정하는것
- 대상 : 엔티티, 임베디드 타입, 스칼라타입(기본 데이터 타입)
- SELECT m FROM Member m : 엔티티 프로젝션
- SELECT m.team FROM Member m : 엔티티 프로젝션
- SELECT m.address FROM Member m : 임베디드 타입 프로젝션
- SELECT m.userName, m.age FROM Member m : 스칼라 타입 프로젝션
Join 과 Fetch Join 차이점
Join
- Fetch Join과 달리 연관 Entity에 Join을 걸어도 실제 쿼리에서 SELECT 하는 Entity는 오직 JPQL에서 조회하는 주체가 되는 Entity만 조회하여 영속화
- 조회의 주체가 되는 Entity만 SELECT 해서 영속화하기 때문에 데이터는 필요하지 않지만 연관 Entity가 검색 조건에는 필요한 경우에 주로 사용한다.
Fetch Join?
- JPQL에서 성능 최적화를 하기 위해 사용하는 기능
- 조회의 주체가 되는 Entitiy이외에 Fetch Join이 걸린 연관 Entity도 함께 SELECT하여 모두 영속화 (즉시 로딩)
- 즉시 로딩 : 어떠한 엔티티가 조회되었을 때 연관된 엔티티도 모두 함께 조회
- 지연 로딩 : 어떠한 엔티티가 조회되었을 때 연관된 엔티티는 Proxy로 들어가게 되고, 실제로 사용될 때 DB에서 조회해서 사용
- 주의점 : 엔티티를 조회하지만, 연관된 엔티티는 필요하지 않음에도 조회를 하기 때문에 성능상 이슈가 발생할 수 있다.
- 엔티티를 조회할 때 Fetch Join을 사용한다면, 개발자의 의도 하에 한 번의 Query로 연관된 엔티티를 같이 조회할 수 있다. ⇒ 연관된 엔티티가 필요하지 않을 땐 Proxy가 들어오며, 필요할 때는 실제 객체를 조회할 수 있게 되어 즉시 로딩의 문제점을 보완