[JPA] JPQL(Java Persistence Query Language)

동동·2022년 4월 24일
0

JPA

목록 보기
16/18
post-thumbnail

JPQL

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

📌 JPQL 문법

  • select m from Member as m where m.age > 18
  • 엔티티와 속성은 대소문자 구분O(Member, age)
  • JPQL 키워드는 대소문자 구분X(SELECT, select, FROM, from)
  • 엔티티 이름 사용, 테이블 이름이 아님(Member)
  • 엔티티 이름은 따로 설정하지 않으면 클래스명과 같음
  • 별칭은 필수(m) (as는 생략 가능) -> 기존 native sql에서는 별칭을 사용할 때 as를 썻음

🚧 산술

🚧 집합과 정렬

  • GROUP BY, HAVING
  • ORDER BY

🚧 TypeQuery, Query

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

// username(String) / age(int) 선택하고자 하는 두 컬럼의 데이터 타입이 달라서 타입을 설정해 줄 수 없음
Query query = em.createQuery("select m.username, m.age from Member m");

🚧 결과 조회 API

  • query.getResultList() : 결과가 하나 이상일 때 리스트 반환, 결과가 없으면 빈 리스트 반환
  • query.getSingleResult() : 결과가 정확히 하나로 단일 객체 반환
    • 결과가 없을 때 : javax.persistence.NoResultException 발생
    • 결과가 둘 이상일 때 : javax.persistence.NonUniqueResultException 발생

그럼 애초에 번거롭지 않게 getResultList()를 사용하면 될거 같은데 왜 굳이 getSingleResult()를 사용할까? 메모리 절약 차원에서?? 리스트 결과를 가져오면 loop를 돌려야 하니까?

🚧 Parameter Binding - 이름 기준 / 위치 기준

이름 기준

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

위치 기준

Member result = em.createQuery("select m from Member m where m.username = ?1", Member.class)
       .setParameter(1, "member1")
       .getSingleResult();
  • 위치 기준의 파라미터 바인딩은 쓰지 않는 것이 좋음
    기존 순서 중간에 삽입을 하면 오류가 발생할 확률이 큼
    이름 기반은 중간에 순서가 바껴도 문제 없음
profile
괴발개발

0개의 댓글