JPA 객체지향 쿼리 언어(JPQL) - 경로 표현식

2022. 7. 20. 23:14·공부/JPA
반응형

출처 : 자바 ORM 표준 JPA 프로그래밍 인프런 강의

 

JPA 게시글은 대부분 인프런의 김영한님의 강의인 '자바 ORM 표준 JPA 프로그래밍' 기반으로 내용을 정리했습니다.

 

경로 표현식

  • .(점)을 찍어 객체 그래프를 탐색하는 것
select m.username // 상태 필드
   from Member m
    	join m.team t // 단일 값 연관 필드
        join m.orders o // 컬렉션 값 연관 필드
where t.name = "팀A"
  • 위 세 가지 각자 내부적으로 동작하는 방식이 달라지므로 구분을 잘해서 이해해야 한다.
  • 상태 필드(state field) : 단순히 값을 저장하기 위한 필드
  • 연관 필드(association field) : 연관관계를 위한 필드
    • 단일 값 연관 필드 : @ManyToOne, @OneToOne, 대상이 엔티티
    • 컬렉션 값 연관 필드 : @OneToMany, @ManyToMany, 대상이 컬렉션

 

 

경로 표현식 특징

  • 상태 필드(state field) : 경로 탐색의 끝, 탐색 X
select m.username From Member m

상태 필드의 경우 username 필드에 접근한 후 더 이상 접근할 필드나 속성이 존재하지 않는다. 그래서 더이상 탐색이 불가능하다.

  • 단일 값 연관 경로 : 묵시적 내부 조인(inner join) 발생, 탐색 O
select m.team From Member m

단일 값 연관 경로의 경우엔 Member 안에 team에 접근 후 team안에 있는 다양한 필드에 더 접근할 수 있어 탐색이 가능하다.

m.team.name

위 표현식의 경우 name이 상태 필드인 경우엔 이 역시 경로 탐색의 끝이므로 더 이상의 탐색이 불가능하다.

묵시적 내부 조인의 경우엔 위 예제를 실행해보면 나오는 로그를 보면 알 수 있다.

Hibernate: 
    /* select
        m.team 
    from
        Member m */ select
            team1_.id as id1_3_,
            team1_.name as name2_3_ 
        from
            Member member0_ 
        inner join //** join이 일어난다.
            Team team1_ 
                on member0_.TEAM_ID=team1_.id

이런 현상이 일어나는 이유는 객체에서야 점 표기법으로 간단하게 가져오면 되지만 DB에서는 Member에 있는 Team의 컬럼과 값을 가져오려면 어쩔 수 없이 join이 일어나게 된다. 이런 현상을 묵시적 내부 조인이라 한다. 
뭔가 간단해 보여서 좋아 보이지만 오히려 실무에서는 잘 쓰지 않는다고 한다. 왜냐하면 쿼리 튜닝 부분에서 어려움을 겪을 수 있기 때문이다. 그래서 웬만하면 묵시적 내부 조인이 일어나지 않게 쿼리를 작성하는 것이 좋다. 그리고 또 다른 이유는 예제처럼 작성할 경우 의도치 않는 JOIN문이 계속 발생하면 한 번에 찾기가 힘들어서 웬만하면 JPA라도 큰 애플리케이션에서는 SQL과 비슷하게 작성하는 것이 좋다.

  • 컬렉션 값 연관 경로 : 묵시적 내부 조인 발생, 탐색 X
    • FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색이 가능하다.
String query = "select t.members from Team t";

컬렉션의 경우 점 표기법으로 더 이상 가져올만한 게 없다. t.members 뒤에 점(.)을 찍으면 자동완성으로 나오는 게 size 밖에 없다. 즉, 탐색이 불가능하다. 만약 members에 있는 username을 가져오고 싶을 경우엔 명시적 조인을 사용하면 된다.

String query = "select m.username from Team t join t.members m";
  • 뭔가 설명이 생각보다 복잡해졌지만 결론은 실무에서는 묵시적 내부 조인을 일으킬만한 쿼리를 작성하지 않는 것이 좋다. 

 

 

단일 값 연관 경로 탐색

  • JPQL : select o.member from Order o
  • SQL
select m.*
	from Orders o
    inner join Member m on o.member_id = m.id
  • 위 JPQL로 작성한 쿼리도 묵시적 내부 조인이 발생한다. 고로 사용하지 않는 게 좋다.

 

 

명시적 조인, 묵시적 조인

  • 명시적 조인 : join 키워드 직접 사용
    • select m from Member m join m.team t
  • 묵시적 조인 : 경로 표현식에 의해 묵시적으로 SQL 조인 발생(내부 조인만 가능)
    • select m.team from Member m

 

 

경로 탐색을 사용한 묵시적 조인 시 주의사항

  • 항상 내부 조인
  • 컬렉션은 경로 탐색의 끝, 명시적 조인을 통해 별칭을 얻어야 한다.
  • 경로 탐색은 주로 SELECT, WHERE 절에서 사용하지만 묵시적 조인으로 인해 SQL의 FROM (JOIN) 절에 영향을 준다.

 

 

실무 조언

  • 가급적 묵시적 조인 대신에 명시적 조인 사용
  • 조인은 SQL 튜닝에 중요 포인트
  • 묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어려움

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • JPA 객체지향 쿼리 언어(JPQL) - 패치 조인(한계)
  • JPA 객체지향 쿼리 언어(JPQL) - 패치 조인(기본)
  • JPA 객체지향 쿼리 언어(JPQL) - JPQL 함수
  • JPA 객체지향 쿼리 언어(JPQL) - 조건식(CASE 등)
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    알고리즘
    RESTful
    react
    스프링부트
    프로그래머스
    IT
    방통대
    Java
    에러해결
    oracle
    프론트엔드
    자바스크립트
    토비의스프링부트
    넥사크로
    토이프로젝트
    운영체제
    MSA
    개발자
    SQL
    QueryDSL
    기출문제
    springboot
    egov
    인프런
    코딩테스트
    Spring
    SpringBoot를 이용한 RESTful Web Service 개발
    전자정부프레임워크
    JPA
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
JPA 객체지향 쿼리 언어(JPQL) - 경로 표현식
상단으로

티스토리툴바