JPQL과 쿼리 API
작성일 2025-08-06 · 분류: Spring Boot, JPA
※ 로딩 전략 · N+1 · EntityGraph · 배치 페치 · 페치 조인 튜닝은 JPA-03-loading에 있음. 본 문서는 JPQL/쿼리 문법과 API에 집중.
쿼리 API(엔티티 매니저)
EntityManager.createQuery로 JPQL 실행. TypedQuery<T>를 우선 사용하고,
파라미터는 이름 기반을 권장한다.
프로젝션(SELECT)
프로젝션은 엔티티, 임베디드, 스칼라, DTO(new …)를 지원. 스칼라 혼합은 Object[] 반환이므로 DTO로 직접 투영하면 깔끔하다.
페이징
setFirstResult, setMaxResults로 구현. (페치 조인 제약은 JPA-03 참고)
조인
명시적 조인을 사용하자. 묵시적 조인은 의도치 않은 내부 조인을 유발할 수 있다. (로딩 전략 자체는 JPA-03 참고)
서브쿼리
JPQL은 WHERE/HAVING 절에서 서브쿼리를 지원. FROM 절 서브쿼리는 불가하므로 필요 시 조인/뷰/네이티브를 고려한다.
경로 표현식
상태 필드(m.name)는 탐색 끝. 단일 값 연관(m.team)은 묵시적 내부 조인이 발생,
컬렉션(t.members)은 탐색 불가이므로 조인 + 별칭이 필요. 크기는 size().
조건식(CASE 등)과 타입/기타 식
단순/검색 CASE를 모두 지원. 상속 구조에서는 TYPE()과 JPA 2.1+의 TREAT로 다운캐스팅 가능.
JPQL 함수
표준(문자/숫자/날짜, size(), index()) + 공급자 함수는
function('name', …)으로 호출한다.
페치 조인 1 — 기본
연관을 한 번에 로딩하는 조인. 자세한 튜닝/제약은 JPA-03 참고—여기선 문법만 다룸.
페치 조인 2 — 한계
컬렉션 페치 조인은 페이징 불가, 다중 컬렉션 페치 조인은 사실상 금지. 중복/카디널리티 폭증으로 데이터 왜곡이 발생할 수 있어 화면 요구에 맞춰 DTO/쿼리 분리 권장.
다형성 쿼리
상속 매핑에서 TYPE()으로 구체 타입 필터, TREAT()로 다운캐스팅 가능.
엔티티 직접 사용 (식별자 비교 자동 변환)
JPQL에서 엔티티를 직접 비교하면 식별자 비교로 자동 변환된다. 연관 필드 비교도 동일.
Named 쿼리
정적 쿼리를 엔티티에 선언해 재사용·검증을 강화. 시작 시 파싱되어 오타를 조기 발견 가능.
벌크 연산
update/delete 벌크는 1차 캐시를 우회해 DB에 바로 반영된다. 실행 후 em.clear()로 상태 동기화를 권장. (로딩 규칙은 JPA-03 참고)
체크리스트
- 쿼리 API는 TypedQuery + 이름 파라미터 우선.
- 프로젝션은 DTO(new …)로 직접 투영하면 깔끔.
- 페이징은
setFirstResult/setMaxResults(페치 조인 제약은 JPA-03). - 경로 표현식: 단일 연관=묵시적 내부 조인, 컬렉션=명시적 조인.
- 서브쿼리는 WHERE/HAVING만, FROM 서브쿼리는 불가.
- CASE/TYPE/TREAT로 조건·다형성 처리.
- 엔티티 직접 비교 → 식별자 비교로 자동 해석.
- 벌크 연산 후
em.clear()필수.