JPA/JPQL

스프링에서 JPA 직접 쿼리 날리기, JPQL

수달하나 2021. 7. 23. 16:17

JPQL (Java Persistence Query Language)

 

객체지향 쿼리 언어이기 때문에 테이블을 대상으로 쿼리 하는 것이 아니라 엔티티 객체를 대상으로 쿼리 한다.

JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.

JPQL은 결국 SQL로 변환된다.

 

 

  • select_문 :: = select m from Member as m [where_절] [groupby_절] [having_절] [orderby_절]
  • update_문 :: = update m [where_절]
  • delete_문 :: = delete m [where_절]

엔티티와 속성은 대소문자를 구문하고 JPQL 키워드는 대소문자를 구분하지 않는다.

테이블의 이름이 아닌 엔티티의 이름을 사용하고 별칭(m)은 필수로 사용한다 (as 는 생략이 가능)

 

 

TypedQuery : 반환 타입이 명확할 때 사용

Query : 반환 타입이 명확하지 않을 때 사용

TypedQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class); 

Query query = em.createQuery("SELECT m.username, m.age from Member m");

 

 

쿼리 결과 조회 API

 

결과가 하나 이상일 때, 리스트 반환 getResultList()를 사용하고 결과가 없다면 빈 리스트를 반환하게 된다.

결과가 정확하게 하나일 때는 단일 객체를 반환하는 getSingleResult()를 사용한다. 이때 결과가 없거나 둘 이상일 경우 예외를 발생시킨다.

 

결과가 없을 경우: javax.persistence.NoResultException

결과가 둘 이상일 경우: javax.persistence.NonUniqueResultExceprion 

 

 

프로젝션

 

SELECT 절에 조회할 대상을 지정하는 것

프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 데이터 타입)

  • SELECT m FROM Member m -> 엔티티 프로젝션 
  • SELECT m.team FROM Member m -> 엔티티 프로젝션 
  • SELECT m.address FROM Member m -> 임베디드 타입 프로젝션
  • SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션(데이터 나열)

 

페이징 API

 

JPA는 페이징을 두 API로 추상화 한다.

  • setFirstResult(int startPosition) : 조회 시작 위치
  • setMaxResult(int maxResult): 조회할 데이터 수
Query query = em.createQuery("SELECT m.username, m.age from Member m order by m.age desc").setFirstResult(1).setMaxResults(10);

 

조인

 

  • 내부 조인
List<Member> memberList = em.createQuery("SELECT m from Member m inner join m.team t", Member.class).getResultList();
  • 외부 조인
List<Member> memberList = em.createQuery("SELECT m from Member m left join m.team t", Member.class).getResultList();
List<Member> memberList = em.createQuery("SELECT m from Member m outer join m.team t", Member.class).getResultList();
  • 세타 조인
List<Member> memberList = em.createQuery("SELECT m from Member m Team t where m.username = t.name, Member.class).getResultList();

 

 

기타 타입 표현

  • 문자: ‘HELLO’, ‘She’, ’s’
  • 숫자: 10L(Long), 10D(Double), 10F(Float)
  • Boolean: TRUE, FALSE
  • ENUM: jpabook.MemberType.Admin (패키지명 포함)
  • 엔티티 타입: TYPE(m) = Member (상속 관계에서 사용)
  • EXISTS, IN
  • AND, OR, NOT
  • =, >, >=, <, <=, <>
  • BETWEEN, LIKE, IS NULL