본 글은 김영한님의 <자바 ORM 표준 JPA 프로그래밍>을 읽고 공부한 내용을 정리한 글입니다.
- 객체지향 쿼리 소개
- JPQL
- Criteria
- QueryDSL
- Native SQL
- 객체지향 쿼리 심화
이번 글에서는 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 문은 없다.
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을 직접 적어주는 것이다.
- 묵시적 조인 : 경로 표현식에 의해 묵시적으로 조인이 일어나는 것이다.