[Spring] JPQL 기초 (1)

이연우·2025년 8월 20일

TIL

목록 보기
95/100

📝 기본 문법

  • JPQL은 Entity 객체를 대상으로 SQL Query를 생성
    (SQL처럼 보이지만 대상은 테이블/컬럼이 아닌 엔티티/필드)

📌 JPQL 문법 규칙

  1. 테이블 이름 ❌ → Entity 이름 사용 (클래스명이 기본값)
  2. Entity와 필드는 대소문자 구분
  3. JPQL 키워드(SELECT, FROM, WHERE 등)는 대소문자 구분 없음
  4. 별칭(alias) 필수, AS는 생략 가능

🧩 기본 문법 구조

SELECT <별칭> 
FROM <엔티티 이름> [AS <별칭>] 
[WHERE 조건] 
[GROUP BY 속성] 
[HAVING 조건] 
[ORDER BY 속성]
  • update, delete도 사용 가능
  • GROUP BY, HAVING, ORDER BY 같은 집계/정렬 기능 제공

🔢 집계 함수 예시:

select
    SUM(p.price),  -- 총합
    AVG(p.price),  -- 평균
    MAX(p.price),  -- 최대
    MIN(p.price),  -- 최소
    COUNT(p)       -- 개수
from Product p

🎯 반환 타입 및 결과

  • JPQL 실행 → JPA 쿼리 APIQueryTypedQuery 사용

🔄 반환 타입 메서드

1️⃣ TypedQuery

  • 반환 타입이 명확할 때 (엔티티, 특정 필드 등)
  • 컴파일 시점에 타입 검사 가능 → 안정적

예시:

TypedQuery<Tutor> q1 = em.createQuery("select t from Tutor t", Tutor.class);
TypedQuery<String> q2 = em.createQuery("select t.name from Tutor t", String.class);

2️⃣ Query

  • 반환 타입이 명확하지 않을 때 사용
  • 결과가 여러 타입 섞이면 ObjectObject[]로 반환 → 형 변환 필요

예시:

Query query = em.createQuery("select t.name, t.age from Tutor t");

📊 비교: TypedQuery vs Query

특징QueryTypedQuery
타입 안정성낮음 (Object 반환)높음 (지정 타입 반환)
사용 목적결과 타입 불명확결과 타입 명확
형 변환필요 (Casting)자동 변환
결과 처리Object, Object[]지정한 클래스 타입

👉 대부분의 경우 TypedQuery 사용 권장

📥 결과 조회 메서드

1️⃣ getResultList()

  • 결과 하나 이상List 반환
  • 결과 없으면 List 반환

예시:

List<Tutor> list = em.createQuery("select t from Tutor t", Tutor.class).getResultList();

2️⃣ getSingleResult()

  • 결과 딱 하나일 때만 사용
  • 없으면 → NoResultException
  • 여러 개면 → NonUniqueResultException

예시:

Tutor t = em.createQuery("select t from Tutor t where t.id = 1L", Tutor.class)
            .getSingleResult();

💡 Spring Data JPA에서는 결과가 없을 경우 null 또는 Optional로 반환


🎛️ 파라미터 바인딩

  • 쿼리에 동적으로 값 전달 → SQL 인젝션 방지 + 쿼리 재사용 가능

1️⃣ 이름 기반 바인딩 (권장 ✅)

Tutor wonuk = em.createQuery(
    "select t from Tutor t where t.name = :name", Tutor.class)
    .setParameter("name", "wonuk")
    .getSingleResult();

System.out.println(wonuk.getName());
System.out.println(wonuk.getAge());
  • 메서드 체이닝 가능
  • 가장 안전하고 가독성 좋음

2️⃣ 위치 기반 바인딩 (비추천 ❌)

Tutor wonuk2 = em.createQuery(
    "select t from Tutor t where t.age = ?1", Tutor.class)
    .setParameter(1, 100)
    .getSingleResult();
  • 순서가 바뀌면 전체 수정 필요 → 유지 보수 어려움
  • 실무에서는 잘 사용하지 않음

🧠 요약 정리

구분핵심 내용
문법 규칙① 엔티티 이름 사용(테이블X)
② 엔티티·필드: 대소문자 구분
③ 키워드: 대소문자 구분 없음
④ 별칭(alias) 필수, AS 생략 가능
기본 문법SELECT ... FROM 엔티티 [WHERE] [GROUP BY] [HAVING] [ORDER BY]
update, delete도 가능
집계 함수SUM, AVG, MAX, MIN, COUNT
반환 타입- TypedQuery: 반환 타입 명확, 타입 안정성 ↑
- Query: 반환 타입 불명확, 캐스팅 필요
결과 조회- getResultList(): 결과 여러 개 → List 반환 (없으면 빈 List)
- getSingleResult(): 결과 1개만 반환
(없으면 NoResultException,여러 개면 NonUniqueResultException)
Spring Data JPA 차이결과 없으면 null 또는 Optional 반환
파라미터 바인딩- 이름 기반(\:name) → 권장 (안전·가독성 좋음)
- 위치 기반(?1) → 비추천 (순서 바뀌면 수정 필요)

0개의 댓글