[JPA] JPQL - 기본 문법과 기능
11 Aug 2022해당 포스트는 인프런 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 을 듣고 정리한 글입니다.
JPQL - 기본 문법과 기능
JPQL
소개
- JPQL은 객체지향 쿼리 언어다.따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
- JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다.
- JPQL은 결국 SQL로 변환된다.
JPQL 문법
개요
- select m from Member as m where m.age > 18
- 엔티티와 속성은 대소문자 구분O (Member, age)
- JPQL 키워드는 대소문자 구분X (SELECT, FROM, where)
- 엔티티 이름 사용, 테이블 이름이 아님(Member)
- 별칭은 필수(m) (as는 생략가능)
예시
select_문 :: =
select_절
from_절
[where_절]
[groupby_절]
[having_절]
[orderby_절]
update_문 :: = update_절 [where_절]
delete_문 :: = delete_절 [where_절]
update, delete는 벌크현상이라해서, 여러건을 한번에 업데이트를 치도록 JPA가 쿼리를 날린다.
집합과 정렬
- GROUP BY, HAVING
- ORDER BY
select
COUNT(m), //회원수
SUM(m.age), //나이 합
AVG(m.age), //평균 나이
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
TypeQuery, Query
- TypeQuery: 반환 타입이 명확할 때 사용
TypedQuery<Member> query1 = entityManager.createQuery("SELECT m FROM Member m", Member.class);
TypedQuery<String> query2 = entityManager.createQuery("SELECT m.username FROM Member m", String.class);
query1
, query2
필드를 보면, m으로 컬럼을 호출해 Member.class로 반환하거나, String 타입인 m.username만 쿼리를 반환한다. 이렇게 반환값이 하나로 분명할 경우에는 TypeQuery를 사용할 수 있다.
- Query: 반환 타입이 명확하지 않을 때 사용
Query query3 = entityManager.createQuery("SELECT m.username, m.age FROM Member m");
String 타입인 m.username와 int 타입인 m.age가 같이 반환되어 반환 타입이 특정되지 않을 경우에는 Query를 사용해서 쿼리값을 반환받는다.
결과 조회
-
query.getResultList(): 결과가 하나 이상일 때, 리스트 반환
- 결과가 없으면 빈 리스트 반환
-
query.getSingleResult(): 결과가 정확히 하나, 단일 객체 반환
- 결과가 없으면: javax.persistence.NoResultException
- 둘 이상이면: javax.persistence.NonUniqueResultException
getResultList()
는 무조건 빈 List를 반환하기 때문에 NPE(NullPointException)의 위험이 없다,
하지만 getSingleResult()
의 경우 무조건 객체가 하나일 경우에만 반환하고 결과가 없거나 둘일경우 예외를 반환하기 때문에 주의해서 코드를 작성해야 한다.
파라미터 바인딩 - 이름 기준, 위치 기준
JPQL에서는 파라미터를 지정해 줄 수 있다.
/* 파라미터 바인딩 */
TypedQuery<Member> query = entityManager.createQuery("SELECT m FROM Member m WHERE m.username = :username", Member.class);
query.setParameter("username", "member1");
Member member1 = query.getSingleResult();
System.out.println("member1 : " + member1.getUsername());
/* SELECT
m
FROM
Member m
WHERE
m.username = :username */ select
member0_.id as id1_0_,
member0_.age as age2_0_,
member0_.TEAM_ID as team_id4_0_,
member0_.username as username3_0_
from
Member member0_
where
member0_.username=?
member1 : member1