Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

지우쓰 개발일기

[JPA] JPQL (1) 본문

Spring Boot/JPA

[JPA] JPQL (1)

jiwoo-kimm 2020. 9. 17. 02:58

본 포스팅은 자바 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
Comments