본 포스트는 김영한 님의 자바 ORM 표준 JPA 프로그래밍 강의를 토대로 작성하였습니다.
JPA에서 지원하는 SQL을 추상화한 객체지향 쿼리 언어 이다. 특징은 테이블이 아닌 객체를 대상으로 쿼리를 진행하며, SQL을 추상화해서 특정 데이터베이스 SQL에 종속되지 않는다.
즉, 객체 대상으로 한 SQL 문이 JPQL 이고 JPA가 이걸 실제 데이터베이스를 대상으로 한 SQL 문법으로 바꾸어(각 DBMS용 SQL에 맞게) 쿼리를 날려준다.
TypedQuery : 반환 타입이 명확할 때 사용
예시) TypedQuery query = em.createQuery("SELECT m FROM Member m", Member.class);
Query : 반환 타입이 명확하지 않을 때 사용
예시)
Query query = em.createQuery("SELECT m.username, m.age from Member m");
query.getResultList() : 결과가 하나 이상일 때 리스트 반환
query.getSingleResult() : 결과가 정확히 하나, 단일 객체 반환
SELECT 절에 조회할 대상을 지정하는 것
프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입
예시 코드
select m.username, m.age from Member m
Query 타입으로 조회
-> 특정한 타입을 명시하지 않으면 Query 형태로 조회된다. 예시는 아래를 참고하자.
Object[] 타입으로 조회
List resultList = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = resultList.get(0);
Object[] result = (Object[]) o;
System.out.println("username = " + result[0]);
System.out.println("age = " + result[1]);
다음과 같이 createQuery 함수에 두 번째 인자로 클래스를 적어주지 않으면 그냥 Object[] 를 담은 List가 반환된다. 따라서 다음과 같이 사용할 수 있다.
new 명령어로 조회
List<MemberDTO> resultList = em.createQuery("select new com.example.jpabook.jpashop.domain.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
.getResultList();
위 코드와 같이 new 명령어를 작성해주고 반환을 DTO로 받는 형태이다. 이 때 DTO에 정의된 생성자를 이용하므로 쿼리문 형식에 해당하는 생성자가 반드시 존재해야 한다.
코드
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(0)
.setMaxResults(10)
.getResultList();
System.out.println("resultSize: " + result.size());
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
다음과 같이 시작할 인덱스와 몇 개 가져올지만 정해주면 된다. (정말 간단하다!)
SELECT m FROM Member m [INNER] JOIN m.team t
inner는 생략 가능하다. 내부 조인 시 두 테이블에 모두 데이터가 존재해야 가져온다.SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
outer는 생략 가능하다. 두 테이블 중 하나에 데이터가 없더라도 모두 긁어온다.SELECT count(m) FROM Member m, Team t where m.username = t.name
전혀 관계가 없는 Member와 Team 테이블을 카르테시안 곱해서 모두 가져온 뒤 where 절의 조건에 따라 필터링해서 가져온다.쿼리 안에 쿼리를 넣을 수 있다. 이 안에 넣은 쿼리를 서브 쿼리라고 한다.
예시 코드)
select m from Member m
where m.age > (select avg(m2.age) from Member m2)