JPQL은 JPA를 다루는 개발자라면 필수로 학습해야 하는 객체지향 쿼리 언어이다.
JPA를 사용해 엔티티를 조회할 때 식별자로 조회하는 방법인 EntityManager.find()가 있고,
연관된 객체들을 통해 a.getB()처럼 객체 그래프 탐색을 하는 간단한 방법이 존재한다.
하지만 애플리케이션을 만들다 보면 조건을 추가해야 하는 부분이 있다. 예를 들면 부서가 인사과이고 연봉이 4000 이상인 사람만 필요할 경우 조건절이 필요한데 간단한 객체 그래프 탐색이나 식별자로 조회하는 방법은 맞지 않는다.
이전 내가 사용했던 MyBatis는 쿼리를 직접 작성하여 DB와 연동했으므로 이러한 조건에 대해서 자유로 뒀지만 이것이 장점이자 단점이 되었다.
JPA는 테이블을 중점으로 개발하는 것이 아닌 객체를 대상으로 개발하므로 검색도 엔티티 객체를 대상으로 하는 방법이 필요하다.
이러한 문제를 해결하기 위해 JPQL이 만들어졌는데 JQPL은 테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리이며, SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다는 특징이 있다.
이 SQL추상화를 구체적으로 말하자면 직접 쿼리 입력이 필요한 경우는 어쩔 수 없이 특정 데이터베이스 SQL에 의존하여 작성하여야 하는데 JPQL로 대체하면 JPA가 데이터베이스가 변경되어도 의존되지 않고 독립적으로 쿼리를 수행하게 도와준다는 이야기이다.
JPQL을 사용하면 JPA는 JPQL을 분석한 다음 적절한 SQL을 만들어 데이터베이스를 조회하고 그 결과로 엔티티 객체를 생성한 후 반환한다. SQL과 비슷한 문법을 가지고 있으니 몇 가지 차이점만 숙지하자.
package chap13;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
@Entity
public class Member {
@Column(name = "name")
private String username;
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("spring5");
EntityManager em = emf.createEntityManager();
String jpql = "select m from Member as m where m.username = 'sung'";
//jpql을 이용한 구체적인 조회
List<Member> resultList = em.createQuery(jpql,Member.class).getResultList();
}
}
여기서 m.username은 테이블의 name칼럼이 아니라 Member.username을 의미한다.
혹시 쿼리를 직접 사용하면 오타가 발생할 수도 있고 그래도 컴파일은 성공하고 서버에 배포했다고 하자.
그럼 쿼리 실행 시점에 런타임 오류가 발생하는데, 이것이 문자 기반 쿼리의 단점이다.
이 단점을 보완해주는 것은 Criteria라는 JPQL을 생성하는 빌더 클래스가 존재한다.
Criteria는 문자가 아닌 코드로 JPQL을 작성한다.
위의 문자 기반 쿼리를 Criteria로 변경해보자.
CriteriaBuilber cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq =
query.select(m).where(cb.equal(m.get(Member_.username), "sung"));
List<Member> resultLit = em.createQuery(cq).getResultList();
그런데 너무나도 복잡하고 장황하다. 코드도 한눈에 들어오지 않는다.
이러한 단점을 보안할 QueryDSL이 존재한다. QueryDSL 또한 JPQL 빌더 역할을 한다. 장점은 코드 기반이면서 단순하고 사용하기가 쉽다는 것이다. 다만 JPA표준은 아니고 오픈소스 프로젝트이다.
다시 한번 JPQL 특징을 정리해보자.
-
JPQL은 객체지향 쿼리 언어이다. 따라서 테이블을 대상으로 쿼리 하는 것이 아닌 엔티티 객체를 대상으로 쿼리 한다.
-
JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다.
-
JPQL은 결국 SQL로 변환된다.
'데이터 접근 기술 > JPA' 카테고리의 다른 글
[JPA] JPQL JOIN (0) | 2021.01.31 |
---|---|
[JPA] JPQL 기본 문법과 SELECT 절 (0) | 2021.01.31 |
[JPA] 즉시 로딩과 지연 로딩 (0) | 2021.01.28 |
[JPA] 상속 관계 매핑 (0) | 2021.01.27 |
Entity 매핑 (0) | 2020.09.03 |
댓글