지우쓰 개발일기
[JPA] JPQL (1) 본문
본 포스팅은 자바 ORM 표준 JPA 프로그래밍 (김영한 저)을 읽고 정리한 내용입니다.
자바 ORM 표준 JPA 프로그래밍
에이콘 오픈 소스 프로그래밍 시리즈. 이 책은 JPA 기초 이론과 핵심 원리, 그리고 실무에 필요한 성능 최적화 방법까지 JPA에 대한 모든 것을 다룬다.
www.aladin.co.kr
기본 문법과 쿼리 API
SELECT 문
-
대소문자 구분
-
엔티티와 속성 대소문자 구분
-
JPQL 키워드는 구분 X
-
-
JPQL에서 사용하는 '타입'은 클래스가 아닌 엔티티 이름
-
별칭 지정 필수
TypeQuery, Query
-
실행할 쿼리 객체
-
TypeQuery: 반환 타입 명확하게 지정
-
Query: 반환 타입 미지정
- SELECT 절의 조회 대상이 하나인 경우: Object 반환
- 둘 이상인 경우: Object[] 반환
-
결과 조회
-
query.getResultList()
-
List로 반환
- 결과 없는 경우 빈 컬렉션 반환
-
- query.getSingleResult()
- 결과 없는 경우 javax.persistence.NoResultException 발생
- 결과 1개보다 많은 경우 javax.persistence.NonUniqueResultException 발생
Parameter Binding
Named Parameters
-
파라미터를 이름으로 구분
-
이름 앞에 ':' 기호를 붙임
-
query.setParameter() 메소드로 바인딩
-
List<Member> members =
em.createQuery("SELECT m FROM Member m WHERE m.username = :username", Member.class)
.setParameter("username", usernameParam)
.getResultList();
Positional Parameters
-
파라미터를 위치값으로 구분
-
위치값 앞에 '?' 기호를 붙임
-
query.setParameter() 메소드로 바인딩
-
List<Member> members =
em.createQuery("SELECT m FROM Member m WHERE m.username = ?1", Member.class)
.setParameter(1, usernameParam)
.getResultList();
💡 Named Parameter Binding 방식을 사용하는 것이 더 명확하며, Parameter Binding은 선택이 아닌 필수다.
Projection
Projection
-
SELECT 절에 조회할 대상을 지정하는 것
-
[SELECT {프로젝션 대상} FROM]
-
엔티티, 임베디드 타입, 스칼라 타입
-
엔티티 프로젝션
SELECT m FROM Member m
SELECT m.team FROM Member m
-
원하는 (엔티티) 객체를 바로 조회
-
조회한 엔티티는 영속성 컨텍스트에서 관리함
임베디드 타입 프로젝션
SELECT a FROM Address a // 잘못된 쿼리
-
임베디드 타입은 조회의 시작점이 될 수 없음
-
조회한 임베디드 타입은 값타입이므로 영속성 컨텍스트에서 관리하지 않음
스칼라 타입 프로젝션
List<String> usernames =
em.createQuery("SELECT username FROM Member m", String.class)
.getResultList();
-
기본 데이터 타입
여러 값 조회
List resultList =
em.createQuery("SELECT m.username, m.age FROM Member m")
.getResultList();
for (Object[] row : resultList) {
String username = (String) row[0];
Integer age = (Integer) row[1];
}
-
스칼라 타입, 엔티티 타입 무관하게 여러 값 함께 조회 가능
-
조회한 엔티티는 영속성 컨텍스트에서 관리함
NEW 명령어
List<UserDTO> resultList =
em.createQuery("SELECT new jpabook.jpql.UserDTO(m.username, m.age) FROM Member m", UserDTO.class)
.getResultList();
- 객체 변환 작업을 줄일 수 있음
-
반환받을 클래스 지정하면 자동으로 클래스의 생성자로 조회 결과 전달
-
패키지 명을 포함한 전체 클래스 명을 입력해야 함
-
클래스에 순서와 타입이 일치하는 생성자 필요
-
Paging API
-
setFirstResult(int startPosition)
-
조회 시작 위치
-
0부터 시작
-
-
setMaxResults(int maxResult)
-
조회할 데이터 수
-
TypedQuery<Member> query =
em.createQuery("SELECT m FROM Member m ORDER BY m.username DESC", Member.class);
query.setFirstResult(10);
query.setMaxResults(20);
query.getResultList();
집합과 정렬
집합 함수
함수 | 기능 | 리턴 타입 |
COUNT | 결과 수 | Long |
MAX, MIN | 최대, 최소 값 | |
AVG | 숫자 평균 값 | Double |
SUM | 숫자 합 | Long, Double, BigInteger, BigDecimal |
GROUP BY, HAVING, ORDER BY
select t.name, COUNT(t.age) as cnt, SUM(m.age)
from Member m LEFT JOIN m.team t
GROUP BY t.name
HAVING AVG(m.age) >= 10
ORDER BY cnt
'Spring Boot > JPA' 카테고리의 다른 글
[JPA] JPQL (3) (0) | 2020.09.21 |
---|---|
[JPA] JPQL (2) (0) | 2020.09.20 |
[JPA] 객체지향 쿼리 개요 (0) | 2020.09.15 |
[JPA] 값 타입 (0) | 2020.09.13 |
[JPA] 영속성 전이, 고아 객체 (0) | 2020.09.13 |