JPA
JPQL 경로 표현식
Beekei
2022. 1. 14. 11:42
반응형
경로 표현식이라는 것은 쉽게 이야기해서 .(점)을 찍어 객체 그래프를 탐색하는 것이다.
"SELECT m.username FROM Member m
JOIN m.team t
JOIN m.orders o
WHERE t.name = '팀A'"
여기서 m.usernam, m.team, m.orders, t.name이 모두 경로 표현식을 사용한 예다.
경로 표현식의 용어 정리
- 상태 필드(state field)
단순한 값을 저장하기 위한 필드(필드 or 프로터티) - 연관 필드(association field)
연관 관계를 위한 필드, 임베디드 타입 포함(필드 or 프로터티)
- 단일 값 연관 필드 : @ManyToOne, @OneToOne, 대상이 엔티
- 컬렉션 값 연관 필드 : @OneToMany, @ManyToMany, 대상이 컬렉션
상태 필드는 단순히 값을 저장하는 필드이고 연관 필드는 객체 사이의 연관관계를 맺기 위해 사용하는 필드다.
@Entity
public class Member {
@Id @GeneratedValue
private long id;
@Column(name = "name")
private String username; // 상태 필드
private int age; // 상태 필드
@ManyToOne(...)
private Team team; // 연관 필드(단일 값 연관 필드)
@OneToMany(...)
private List<Order> orders; // 연관 필드(컬렉션 값 연관 필드)
}
경로 표현식과 특징
상태 필드 경로
경로 탐색의 끝이다. 더는 탐색할 수 없다.
// JPQL
"SELECT m.username, m.age FROM Member m"
// SQL
"SELECT m.name, m.age FROM Member m"
단일 값 연관 경로
묵시적으로 내부 조인이 일어난다. 단일 값 연관 경로는 계속 탐색할 수 있다.
// JPQL
"SELECT o.member FROM Order o"
// SQL
"SELECT m.* FROM Orders o INNER JOIN Member m ON o.member_id = m.id"
Member 테이블과 묵시적 조인이 발생하였다.
컬렉션 값 연관 경로
묵시적으로 내부 조인이 일어난다. 더는 탐색 할 수 없다. 단 FROM 절에서 조인을 통해 별칭을 얻으면 별칭으로 탐색할 수 있다.
JPQL을 다루면서 많이 하는 실수 중 하나는 컬렉션 값에서 경로 탐색을 시도하는 것이다.
"SELECT t.members FROM Team t" // O
"SELECT t.members.username FROM Team t" // X
Team의 묵시적 조인으로 members의 데이터를 조회할 순 있지만 members의 username 컬럼까지 가져오는 건 별칭이 없기 때문에 불가능 하다.
"SELECT m.username FROM Team t JOIN t.members m"
JOIN t.members m으로 별칭을 정해줘야 탐색이 가능하다.
묵시적 조인이란?
경로 표현식에 의해 묵시적으로 조인이 일어나는 것, INNER JOIN만 사용 가능
경로 탐색을 사용한 묵시적 조인 시 주의사항
- 항상 내부 조인이다.
- 컬렉션은 겨로 탐색의 끝이다. 컬렉션에서 경로 탐색을 하려면 명시적으로 조인해서 별칭을 얻어야 한다.
- 경로 탐색은 주로 SELECT, WHERE 절(다른 곳에도 사용됨)에서 사용하지만 묵시적 조인으로 인해 SQL의 FROM 절에 영향을 준다.
조인이 성능상 차지하는 부분은 아주 크다.
묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어렵다는 단점이 있다.
따라서 단순하고 성능에 이슈가 없으면 크게 문제가 안되지만 성능이 중요하면 분석하기 쉽도록 묵시적 조인보다는 명시적 조인을 사용하자.
반응형