본문 바로가기
Study/JPA

객체지향 쿼리 언어 소개

by _비니_ 2024. 7. 27.

📌 소개

 

  • 가장 단순한 조회 방법
    • EntityManager.find()
    • 객체 그래프 탐색(a.getB().getC())
  • 나이가 18살 이상인 회원을 모두 검색하고 싶다면?

JPQL

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 문제는 검색 쿼리
  • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
  • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
  • SQL과 문법 유사,SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
  • JPQL은 엔티티 객체를 대상으로 쿼리
  • SQL은 데이터베이스 테이블을 대상으로 쿼리
  • JPQL을 짜면 SQL로 번역되어 실행이 된다!

 

📌 기본 문법과 쿼리 API

 

  • JPQL은 객체지향 쿼리 언어다. 따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
  • JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다.
  • JPQL은 결국 SQL로 변환된다.

📌 JPQL 문법

select

COUNT(m), //회원수

SUM(m.age), //나이 합

AVG(m.age), //평균 나이

MAX(m.age), //최대 나이

MIN(m.age) //최소 나이

from Member m

 

<집합과 정렬>

  • GROUP BY, HAVING
  • ORDER BY
  • select m from Member as m where m.age > 18 ( Member가 엔티티!!! )
  • 엔티티와 속성은 대소문자 구분O (Member, age)
  • JPQL 키워드는 대소문자 구분X (SELECT, FROM, where)
  • 엔티티 이름 사용, 테이블 이름이 아님(Member)
  • 별칭은 필수(m) (as는 생략가능)

📌 TypeQuery, Query

  • TypeQuery: 반환 타입이 명확할 때 사용
  • Query: 반환 타입이 명확하지 않을 때 사용
//타입이 명확
TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);

//username만 하면 타입을 String으로 잡으면 됨. 
Query query2 = em.createQuery("select m.username from Member m", String.class); 

//But username과 age를 함께 조회하므로 타입이 불명확
Query query3 = em.createQuery("select m.username, m.age from Member m");

 

📌 결과 조회 API

  • query.getResultList(): 결과가 하나 이상일 때, 리스트 반환
    • 결과가 없으면 빈 리스트 반환 (null pointer exception에 대한 걱정 X)
  • query.getSingleResult(): 결과가 정확히 하나, 단일 객체 반환
    • 결과가 없으면: javax.persistence.NoResultException
    • 둘 이상이면: javax.persistence.NonUniqueResultException
    Spring Data JPA는 결과가 없으면 exception을 터뜨리지 않고 null을 반환하거나 optional로 반환

 

📌 파라미터 바인딩 - 이름 기준, 위치 기준

<이름 기준>

Member result = em.createQuery("select m from Member m where m.username = :username", Member.class)
          .setParameter("username", "member1")
          .getSingleResult();
System.out.println("result = " + result);

<위치 기준>

SELECT m FROM Member m where m.username=?1 
query.setParameter(1, usernameParam);

 

되도록이면 위치 기준으로는 쓰지 말고 이름 기준으로만 쓰기!

위치는 중간에 뭐가 추가되고 이럴 경우 다 밀리기 때문.

반응형

'Study > JPA' 카테고리의 다른 글

조인과 서브쿼리  (0) 2024.07.27
프로젝션과 페이징  (0) 2024.07.27
값 타입 2  (0) 2024.07.27
값 타입 1  (0) 2024.07.27
프록시 ) 영속성 전이(CASCADE)와 고아 객체  (0) 2024.07.26