JPQL을 자세히 살펴보기에 앞서 우선 객체지향 쿼리언어가 무엇인지 알아보고 갑시당.
객체지향 쿼리언어란
테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리이다.
SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다
즉 객체지향 SQL이다.
JPA가 공식지원하는 기능
JPQL
Criteria쿼리
네이티브 SQL
JPA가 공식 지원하는 기능은 아니지만 알아둬야 할 것
Qeury DSL
JDBC직접사용, MyBatis같은 SQL매퍼 프레임워크 사용
JPQL소개
Java Persistence Query Language는 엔티티 객체를 조회하는 객체지향 쿼리이다.
JPQL은 SQL을 추상화해서 특정 데이터베이스에 의존하지 않는다. 따라서 Dialect만 수정하면 JPQL을 수정하지 않아도 데이터베이스를 바꿀 수 있다.
@Entity(name = "Member")
public class Member{
@Column(name = "name")
private String username;
}
//JPQL사용
String jpql = "select m from Member as m where m.username = 'kim'";
List<Member> resultList = em.createQuery(jpql, Member.class).getResultList();
//아래와 같은 뜻
select
member.id as id,
member.age as age,
member.team_id as team,
member.name as name
from
Member member
where
member.name = 'kim'
회원 이름이 kim인 엔티티를 조회하는 코드이다. JPQL에서 Member는 엔티티 이름이다. 그리고
m.username은 테이블 컬럼명이 아니라 엔티티 객체의 필드명이다.
em.createQuery()메소드에 실행할 JPQL과 반환할 엔티티의 클래스 타입인 Member.class를 넘겨주고 getREsultList()메소드를 실행하면 JPA는 JPQL을 SQL로 변환해서 데이터베이스를 조회한다. 그리고 조회한 결과로Member 엔티티를 생성해서 반환한다.
Criteria 쿼리 소개
Criteria는 JPQL을 생성하는 빌더 클래스다. Criteria의 장점은 문자가 아닌 qeury.select
(m).where(…)
처럼 프로그래밍 코드로 JPQL을 작성할 수 있다는 점이다.
다음은 Criterial의 장점이다.
컴파일 시점에 오류를 발견할 수 있다.
IDE를 사용하면 코드 자동완성을 지원한다.
동적 쿼리를 작성하기 편하다
//Criteria 사용 준비
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> qeury = cb.createQeury(Member.class);
//루트 클래스(조회를 시작할 클래스)
Root<Member> m = query.from(Member.class);
//쿼리생성
CriteriaQuery<Member> cq = qeury.select(m).where(cb.equal(m.get("username"),"kim"));
List<Member> resultList = em.createQuery(cq).getResultList();
Criteria가 가진 장점이 많지만 모든 장점을 상쇄할 정도로 복잡하고 장황하다. 따라서 사용하기 불편하고 한눈에 들어오지 않는다는 단점이 있다.
QueryDSL소개
QueryDSL도 JQPL빌더 역할을 한다. 코드기반이면서 단순하고 사용하기 쉽다. 그리고 작성한 코드도 JPQL과 비슷해 한눈에 들어온다.
//준비
JPAQuery query = new JPAQuery(em);
QMember member = QMember.member;
//쿼리, 결과조회
List<Member> members = qeury.from(member).where(member.username.eq("kim").list(member);
QueryDSL도 어노테이션 프로세서를 사용해서 쿼리 전용클래슬르 만들어야 한다. QMember는 Member엔티티 클래스를 기반으로 생성ㅎ나 QueryDSL 쿼리 전용 클래스이다.
Native SQL소개
데이터베이스에 의존하는 SQL을 작성해야한다.
오라클에서만 사용하는 CONNECT BY기능 같은 것은 JPQL로도 대체못한다.
String sql = "SELECT ID, AGE, TEAM_ID, NAME FROM MEMBER WHERE NAME = 'kim'";
List<Member> resultList = em.createNativeQuery(sql, Member.class).getResultList();