객체지향 쿼리 언어2 - 중급 문법

bird.j·2021년 6월 1일
0

JPA

목록 보기
10/13

💡 JPQL 페치 조인 - 기본


  • 실무에서 매우매우 중요함
  • SQL 조인 종류 x
  • JPQL에서 성능 최적화를 위해 제공하는 기능
  • 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
  • join fetch 명령어 사용
  • 페치 조인 = LEFT JOIN FETCH 조인경로
@Query("SELECT DISTINCT b " +
              "FROM Board b " +
              "LEFT JOIN FETCH b.boardImgUrls " +
              "LEFT JOIN FETCH b.hearts")
    List<Board> findAllFetchJoin();

distinct를 사용한 이유는 일대다 조인이 있으므로 데이터베이스 row가 증가한다. 그 결과 같은 일(1:N 중 1)의 엔티티의 조회 수도 증가하게 된다. JPA의 distinct는 SQL에 distinct를 추가하고, 더해서 같은 엔티티가 조회되면 애플리케이션에서 중복을 걸러준다. 일의 객체가 컬렉션 페치 조인 때문에 중복 조회 되는 것을 막아준다.

일대다를 페치 조인 하면 페이징이 불가능하다.
컬렉션 페치 조인(일대다)은 1개만 사용할 수 있다. 컬렉션 둘 이상에 페치 조인을 사용하면 안된다. 데이터가 부정합하게 조회될 수 있다.



💡 엔티티 페치 조인


  • 회원을 조회하면서 연관된 팀도 함께 조회(SQL 한 번에)
  • SQL을 보면 회원 뿐만 아니라 팀도 함께 SELECT

JPQL) select m from Member m join fetch m.team
SQL) SELECT M., T. FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID=T.ID

  • 즉시로딩과의 차이점은 쿼리로 어떤 객체를 가져올 것인지 명시 가능



💡 컬렉션 페치 조인


일대다 관계, 컬렉션 페치 조인
JPQL) select t from Team t join fetch t.members where t.name = '팀A'
일대다 조인은 데이터가 뻥튀기 될 수 있다.



💡 페치 조인과 DISTINCT


  • SQL의 DISTINCT는 중복된 결과를 제거하는 명령
  • JPQL의 DISTINCT 2가지 기능 제공
    * SQL에 DISTINCT를 추가
    • 애플리케이션에서 엔티티 중복 제거


💡 페치 조인과 일반 조인의 차이


  • 일반 조인 실행 시 연관된 엔티티를 함께 조회하지 않음
  • JPQL은 결과를 반환할 때 연관관계 고려 x
  • 단지 SELECT 절에 지정한 엔티티만 조회할 뿐
  • 페치 조인을 사용할때만 연관된 엔티티도 함께 조회(즉시로딩 느낌)
  • 페치 조인은 객체 그래프를 SQL 한번에 조회하는 개념



💡 페치 조인 특징과 한계


  • 연관된 엔티티들을 SQL 한 번으로 조회 - 성능 최적화
  • 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함
    * @OneToMany(fetch = FetchType.LAZY)
  • 실무에서 글로벌 로딩 전략은 모두 지연 로딩
  • 최적화가 필요한 곳은 페치 조인 적용
  • 페치 조인 대상에는 별칭을 줄 수 없다.
  • 둘 이상의 컬렉션은 페치 조인할 수 없다.
  • 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.
    * 일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인해도 페이징 가능

0개의 댓글