[Spring] JPQL

이연우·2025년 8월 20일

TIL

목록 보기
94/100

📌 JPQL이란?

  • 데이터베이스에 질의(Query)를 실행하기 위해 사용하는 객체지향 쿼리 언어
  • 테이블/컬럼이 아니라 엔티티/필드를 대상으로 질의

❓ JPQL이 왜 필요할까?

  • em.find()나 연관관계 탐색만으로는 조건 기반 조회가 어렵기 때문에,
    조건이 들어간 SQL이 필요한데 JPA 세계에서는 이를 JPQL로 표준화

🔁 JPA가 지원하는 질의 방식

방식쓰임새장점단점
JPQL정적/일반 쿼리DB 독립적, 객체지향적동적 조건이 많아지면 가독성 저하
QueryDSL동적 쿼리타입 안전, 가독성/유지보수 좋음의존성 추가 필요
Criteria코드 기반 JPQL표준 API너무 장황해 실무 선호도 낮음
Native SQLDB 종속 기능성능/특화 기능 활용이식성 낮음, 엔티티 그래프 이점 적음

🗄️ JPQL의 등장 배경

  • JPA 사용 → 객체 중심 설계
  • 조회 시 em.find() → 엔티티 그래프 탐색(tutor.getCompany())
  • 한계: 모든 데이터를 객체로 변환해 가져올 수 없음
  • 특정 조건 검색 필요 → SQL 같은 기능 필요 → JPQL 등장

📌 예시 코드:

String jpql = "SELECT p FROM Product p WHERE p.price > :minPrice";
List<Product> products = em.createQuery(jpql, Product.class)
                           .setParameter("minPrice", 1000)
                           .getResultList();
  • SELECT p FROM Product p → SQL의 SELECT * FROM product와 대응
  • 최소 가격 이상인 Product 조회

✨ JPQL 특징

  • 객체를 대상으로 검색 (테이블 X)
  • SQL 추상화 → DB 독립적
  • 영속성 컨텍스트 기능 활용 (1차 캐시, 지연 로딩 등)
  • 타입 안정성: 컴파일 시점에 오류 검증 가능

🧰 JPQL vs SQL

특징JPQLSQL
대상Entity & FieldTable & Column
표현 방식객체지향관계형
DB 독립성높음특정 DB 종속
호출 방식EntityManager.createQuery()직접 DB 연결

✍️ JPQL 기본 문법 스냅샷

🔎 기본 조회

String jpql = "select p from Product p where p.price > :minPrice";
List<Product> list = em.createQuery(jpql, Product.class)
                       .setParameter("minPrice", 1000)
                       .getResultList();
  • 대상: Product 엔티티, 별칭 필수(p)
  • 파라미터 바인딩: 이름 기반 :minPrice 권장(인젝션/오타 예방)

🤝 조인 & 패치 조인(지연로딩 최적화)

// 일반 조인
select o from Order o join o.member m where m.name = :name

// 패치 조인(연관 엔티티를 한 번에 로딩)
select o from Order o join fetch o.items
  • 패치 조인으로 N+1 방지,
    컬렉션 패치 조인은 페이징과 상충 주의

🎯 프로젝션(뭘 뽑을 것인가)

// 엔티티
select m from Member m
// 스칼라
select m.name, m.age from Member m
// DTO
select new com.example.MemberDto(m.name, m.age) from Member m

🧮 그룹/정렬/페이징

select d.name, count(e) from Department d join d.employees e
group by d.name having count(e) >= :min

// 페이징
query.setFirstResult(0).setMaxResults(20);

🗃️ 동적 쿼리란?

  • 실행 시점에 조건/값에 따라 변하는 SQL Query 작성 & 실행 방식

💡 JPQL 지원 문법

  • SELECT, WHERE, GROUP BY, HAVING, JOIN 등 사용 가능

📌 예시 코드:

String jpql = "SELECT p FROM Product p WHERE 1=1";

if (name != null) {
    jpql += " AND p.name = :name";
}
if (price != null) {
    jpql += " AND p.price = :price";
}

🌀 JPQL 동적 쿼리의 한계

  • JPQL은 정적 쿼리에 최적화
  • 문자열 직접 조합 → 가독성·유지 보수 어려움
  • 오타/문법 오류 → 컴파일 시점 검증 불가
  • 조건 많아질수록 복잡성 증가

🧠 요약 정리

구분핵심 내용
📚 JPQL 정의객체지향 쿼리 언어, 테이블/컬럼이 아닌 엔티티/필드를 대상으로 작성
🔹 JPA의 Query 지원① JPQL (객체지향 쿼리)
② QueryDSL (동적 쿼리 지원)
③ JPA Criteria (복잡, 잘 안 씀)
④ Native SQL (DB 종속 쿼리 필요 시)
📌 등장 배경em.find() 및 연관관계 탐색만으로 조건 검색 불가 → 조건 기반 SQL 필요 → JPQL 등장
💻 예시 코드SELECT p FROM Product p WHERE p.price > :minPrice → 최소 가격 이상 상품 조회
특징- 엔티티 중심(객체 대상)
- SQL 추상화 → DB 독립적
- 영속성 컨텍스트 활용 가능
- 타입 안정성 제공
🔄 JPQL vs SQLJPQL: Entity & Field, 객체지향, DB 독립적, EntityManager.createQuery()
SQL: Table & Column, 관계형, DB 종속, 직접 DB 연결
⚙️ 동적 쿼리실행 시 조건/값에 따라 변하는 SQL 작성/실행
예: if (name != null) jpql += " AND p.name = :name";
🚨 동적 쿼리 한계- 정적 쿼리에 최적화
- 문자열 직접 조합 필요
- 가독성/유지보수 어려움
- 컴파일 시 오류 검증 불가
- 조건 많아질수록 복잡

0개의 댓글