[JPA] 10장 객체지향 쿼리 언어(1)

diveintoo·2022년 3월 25일
0

본 글은 김영한님의 <자바 ORM 표준 JPA 프로그래밍>을 읽고 공부한 내용을 정리한 글입니다.

  1. 객체지향 쿼리 소개
  2. JPQL
  3. Criteria
  4. QueryDSL
  5. Native SQL
  6. 객체지향 쿼리 심화

이번 글에서는 JPA가 지원하는 복잡한 검색 조건을 사용해서 엔티티 객체를 조회할 수 있는 다양한 쿼리 기술에 대해 알아봅니다.

1. 객체지향 쿼리 소개

1.1 JPQL

  • 엔티티 객체를 조회하는 객체지향 쿼리이다.
  • SQL을 추상화해서 특정 데이터베이스에 의존하지 않는다.
  • SQL보다 간결하다.
    • 엔티티 직접 조회, 묵시적 조인, 다형성 지원

1.2 Criteria

  • JPQL을 생성하는 빌더 클래스이다.
  • 문자가 아닌 프로그래밍 코드로 JPQL을 작성할 수 있다.
  • 컴파일 시점에 오류를 발견할 수 있다.
  • 매우 복잡하기 때문에 사용하기 불편하고 코드도 한눈에 들어오지 않는다.

1.3 QueryDSL

  • JPQL을 생성하는 빌더 클래스이다.
  • 코드 기반이면서 단순하고 사용하기 쉽다.

1.4 Native SQL

  • SQL을 직접 사용할 수 있는 기능이다.
  • 특정 데이터베이스에 의존하는 기능을 사용해야할 때 이용한다.
  • 데이터베이스를 변경하면 함께 수정해야한다는 단점이 있다.

2. JPQL

2.1 기본 문법과 쿼리 API

  • SELECT, UPDATE, DELETE 문을 사용할 수 있다.
  • INSERT 문은 없다.
    • 대신 em.persist() 사용

2.1.1 SELECT 문

  • 엔티티와 속성은 대소문자를 구분한다.
  • 클래스 명이 아닌 엔티티 명을 사용한다.
  • 별칭을 필수로 사용해야 한다.

2.1.2 TypeQuery, Query

  • JPQL을 실행하기 위한 쿼리 객체이다.
  • TypeQuery : 반환할 타입을 명확하게 지정할 수 있을 때
  • Query : 반환할 타입을 명확하게 지정할 수 없을 때

2.2 파라미터 바인딩

2.2.1 이름 기준 파라미터

  • 파라미터를 이름으로 구분하는 방법이다.
  • 이름 기준 파라미터 앞에 :를 사용한다.

2.2.2 위치 기준 파라미터

  • ? 다음에 위치 값을 준다.
  • 위치 값은 1부터 시작한다.

이름 기준 파라미터 바인딩 방식을 사용하는 것이 더 명확하다!

2.3 프로젝션

  • SELECT 절에 조회할 대상을 지정하는 것이다.
  • 프로젝션 대상은 엔티티, 임베디드 타입, 스칼라 타입이 있다.

2.3.1 엔티티 프로젝션

  • 원하는 객체를 바로 조회할 수 있다.
  • 조회한 엔티티는 영속성 컨텍스트에서 관리된다.

2.3.2 임베디드 타입 프로젝션

  • 임베디드 타입은 조회의 시작점이 될 수 없다.
  • 임베디드 타입은 엔티티 타입이 아닌 값 타입이기 때문에 영속성 컨텍스트에서 관리되지 않는다.

2.3.3 스칼라 타입 프로젝션

  • 숫자, 문자, 날짜와 같은 기본 데이터 타입들을 말한다.
  • 중복 데이터를 제거하려면 DISTINCT를 사용한다.

2.4 페치 조인

  • JPQL에서 성능 최적화를 위해 만든 조인이다.
  • 연관된 엔티티나 컬렉션을 한 번에 조회할 수 있는 기능이다.
  • join fetch 명령어로 사용할 수 있다.

특징

  • 페치 조인은 글로벌 로딩 전략보다 우선한다.
    • 글로벌 로딩 전략 : 애플리케이션 전체에 영향을 미치는 엔티티 직접 적용 로딩 전략
    • 글로벌 로딩 전략은 지연 로딩으로 하고, 필요시에만 페치 조인을 적용하는 것이 효과적이다.
  • 지연 로딩이 발생하지 않으므로, 준영속 상태에서도 객체 그래프를 탐색할 수 있다.

한계

  • 페치 조인 대상에는 별칭을 줄 수 없다.
  • 둘 이상의 컬렉션을 페치할 수 없다.
  • 컬렉션을 페치 조인하면 페이지 API를 사용할 수 없다.

2.5 경로 표현식

용어 정리

  • 상태 필드 : 단순히 값을 저장하기 위한 필드
  • 연관 필드 : 연관관계를 위한 필드, 임베디드 타입 포함
    • 단일 값 연관 필드 : @ManyToOne, @OneToOne
    • 컬렉션 값 연관 필드 : @ManyToMany, @OneToMany

2.5.1 상태 필드 경로

  • 경로 탐색의 끝이며 더는 탐색할 수 없다.

2.5.2 단일 값 연관 경로

  • 묵시적으로 내부 조인이 일어난다.
  • 계속 탐색할 수 있다.

2.5.3 컬렉션 값 연관 경로

  • 묵시적으로 내부 조인이 일어난다.
  • 더는 탐색할 수 없다.
  • 조인을 통해 별칭을 얻으면 별칭으로 더 탐색할 수 있다.

조인의 종류

  • 명시적 조인 : JOIN을 직접 적어주는 것이다.
  • 묵시적 조인 : 경로 표현식에 의해 묵시적으로 조인이 일어나는 것이다.
    • INNER JOIN만 할 수 있다.

0개의 댓글