인프런 김영한 강의 정리/자바 ORM 표준 JPA 프로그래밍 기본편

JPA 기본 | JPQL 중급 문법(1) - 경로 표현식

백엔드 개발자 - 젤리곰 2024. 7. 18. 20:39
728x90

1. 경로표현식

점을 찍어 그래프를 탐색하는 것

ex) select m.username from Member m

경로 표현식에는 상태 필드, 단일 값 연관 필드, 컬렉션 값 연관 필드가 있다.

 

2. 상태 필드

상태 필드란, 단순히 값을 저장하기 위한 필드다.

(ex. m.username )

 

오늘 예시로 사용할 Member 엔티티와 Team 엔티티다.

 

✅Member 엔티티

@Entity
@Getter
@Setter
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
}

 

✅Team 엔티티

@Entity
@Getter
@Setter
public class Team {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
}

2-1) 상태 필드 특징

  • 경로 탐색의 끝이다. 
  • 더 이상 탐색할 수 없다.

 

✅상태 필드 예시

select m.username from Member m

m.username은 단순히 값만 저장하기 때문에 뒤에 점을 찍어서 탐색할 수 없다.

m.username.name (X) -> 틀린 문법

 

3. 단일 값 연관 필드

연관 필드란, 연관관계를 위한 필드다.

@ManyToOne, @OneToOne 으로 매핑된 필드

대상이 엔티티다. (ex. m.team)

 

3-1) 단일 값 연관 필드 특징

  • 묵시적 내부 조인(inner join)이 발생한다.
  • 뒤에 점을 찍어서 추가로 탐색할 수 있다.

 

✅단일 값 연관 필드 예시

select m.team from Member m;

 

✅실행되는 쿼리

select
    t1_0.id,
    t1_0.name 
from
    Member m1_0 
join
    Team t1_0 
        on t1_0.id=m1_0.TEAM_ID

- JPQL로 조인을 해주지 않았지만 실제 쿼리가 실행될 때는 조인이 발생한다.

- m.team을 참조할 때 JPA는 내부적으로 'INNER JOIN'을 생성해서 Member와 Team 테이블을 조인한다.

 

💡묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어려우니, 가급적 명시적 조인을 사용하자.

 

4. 컬렉션 값 연관 필드

@OneToMany, @ManyToMany로 매핑된 필드

대상이 컬렉션이다. (ex. m.orders)

 

4-1) 컬렉션 값 연관 필드

  • 묵시적 내부 조인(inner join)이 발생한다.
  • 경로 탐색의 끝이다.
  • 추가 탐색을 할 수 없다. (단, FROM절에 명시적 조인을 통해 별칭을 얻으면 별칭으로 탐색을 할 수 있다.)

💡추가 탐색을 할 수 없는 이유는 어떤 컬렉션 요소를 탐색할 지 지정할 수 없기때문이다.

Item 엔티티 안에 members 를 탐색하고나면 여러 멤버가 엔티티가 있다.

어떤 멤버의 필드를 탐색할 지 알 수 없기때문에 JPA에서 막아놓은 것이다.

 

✅컬렉션 값 연관 필드 예시(묵시적 내부 조인)

select t.members from Team t

 

✅실행되는 쿼리

select
    m1_0.id,
    m1_0.age,
    t1_0.id,
    t1_0.name,
    m1_0.username 
from
    Team t1_0 
join
    Member m1_0 
        on t1_0.id=m1_0.TEAM_ID

- 컬렉션 값 연관 필드를 사용하면 묵시적 내부 조인이 발생한다.

 

✅컬렉션 값 연관 필드 예시(명시적 조인)

select m.username from Team t join t.members m

 

- 컬렉션 값 연관 필드를 사용하면 경로 탐색을 더 이상 못한다고 했지만, FROM 절에 JOIN을 사용해서 t.members에 별칭을 주면 별칭을 통해 탐색할 수 있다.

 

5. 묵시적 조인 주의사항

- 묵시적 조인이란, 경로 표현식에 의해 묵시적으로 SQL 조인이 발생하는 것이다.

- 명시적 조인이란, join 키워드를 직접 사용하는 것이다.

 

  • 묵시적 조인은 항상 내부 조인이 발생한다.
  • 묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어렵다.
  • 조인은 SQL 튜닝에 중요한 포인트다.
  • 묵시적 조인을 쓰면 SQL 튜닝을 어렵게 만든다. 

 

결론 : 묵시적 조인보다는 명시적 조인을 사용하자.

 

728x90