spring/JPA

[JPA] 객체 지향 쿼리 언어 JPQL 2 (기본 문법)

대기업 가고 싶은 공돌이 2024. 7. 29. 01:25

JPQL 문법

jpql 문법은 sql 문법과 동일하다. 

 

  1. 엔티티와 속성은 대소문자를 구분한다. 
    EX) select m from Member as m where m.age > 18 ) 여기서 member와 age의 대소문자가 틀리다면 쿼리가 실패한다.
  2. jpql 키워드는 대소문자를 구분하지 않는다. (select, from ,WHERE 등등 ,,)
  3. 테이블의 이름이 아닌 엔티티의 이름을 사용한다.
  4. 별칭 (m)은 필수이며, as는 생략 가능하다.

집합과 정렬

위의 함수들 및 Group By, HAVING, ORDERBY 모두 지원한다.

 

TypeQuery, Query

TypeQuery: 반환 타입이 명확할 때 사용한다.

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

 

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

Query query = em.createQuery("select m.username, m.age from member m");

 

밑의 예시를 보면 select를 username과 age로 했다. 이런 경우 username은 String 이고 age는 int 여서 어떤 것을 반환 클래스로 둬야하는지 알 수 없다.

 

이러한 경우에 Query를 반환 타입으로 사용한다.

 

결과 조회 API

query.getResultList() : 결과가 하나 이상일 때, 리스트 반환하는 경우 사용

   결과가 없으면 빈 리스트가 반환되니 NullPointException을 걱정하지 않아도 된다.

 

query.getSingleResult(): 결과가 정확히 하나일 때, 단일 객체 반환

   결과가 없으면 javax.persistence.NoResultException

   결과가 둘 이상이면 javax.persistence.NonUniqueResultException이 발생한다.

 

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

List<Member> resultList = query.getResultList();

 

위와 같이 사용하면 된다.

 

jpa를 사용하면 NoResultException이 발생했을 경우 Spring에서 null 또는 Optional을 자동으로 반환해주도록 코드가 짜여있다고 한다.

 

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

두 가지 방식의 파라미터 바인딩을 지원한다.

1. 이름 기준

TypeQuery<Member> query = em.createQuery("select m from Member m where m.username = :username",Member.class);
query.setParameter("username","member1");

 

위와 같은 방식으로 이름 기반의 파라미터 바인딩을 지원한다.

 

2. 위치 기준

 

select m from Member where m.username = ?1;
query.setParameter(1,"member1");

 

위와 같은 방식으로 위치 기반의 파라미터 바인딩도 지원을 하나, 

중간에 파라미터 하나만 끼워 넣어도 뒤의 모든 파라미터의 숫자를 하나 씩 미뤄야 하니 보통 사용하지 않는다.

 

이름 기반의 파라미터 바인딩을 추천한다.

 

 

참고: 김영한, 자바 ORM 표준 JPA 프로그래밍  - 기본편