1. JPQL 페이징
JPQL을 이용해서 페이징 API 예시를 살펴보겠습니다.
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(0).setMaxResults(10).getResultList();
order by까지 해야 제대로 페이징되는지 확인 가능합니다. 시작을 1로 주면 offset limit으로 쿼리가 나갑니다.
2. 조인
- 내부 조인: SELECT m FROM Member m [INNER] JOIN m.team t
- 외부 조인: SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
- 세타 조인: select count(m) from Member m, Team t where m.username = t.name
조인 할 때 'on절'을 활용하여 조인을 할 수 있습니다. 조인 대상을 필터링 할 수 있습니다. 연간관계 없는 엔티티 외부 조인(하이버네이트 5.1부터)
SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'A'
다음은 연관관계가 없는 엔티티 외부 조인 예시입니다. 회원의 이름과 팀의 이름이 같은 대상을 외부조인하는 예제입니다.
SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
3. 서브 쿼리
- [NOT] EXISTS (subquery): 서브쿼리에 결과가 존재하면 참
- {ALL | ANY | SOME} (subquery)
- ALL 모두 만족하면 참
- ANY, SOME: 같은 의미, 조건을 하나라도 만족하면 참
- [NOT] IN (subquery): 서브쿼리의 결과 중 하나라도 같은 것이 있으면
다음은 나이가 평균보다 많은 회원을 조회하는 예시입니다.
SELECT m from Member m where m.age > (select avg(m2.age) from Member m2)
다음은 한건이라도 주문한 고객을 찾는 쿼리입니다.
select m from Member m where (select count(o) from Order o where m = o.member) > 0
이제 서브 쿼리 지원함수를 살펴보겠습니다.
- [NOT] EXISTS (subquery): 서브쿼리에 결과가 존재하면 참
- {ALL | ANY | SOME} (subquery)
- ALL 모두 만족하면 참
- ANY, SOME: 같은 의미, 조건을 하나라도 만족하면 참
- [NOT] IN (subquery): 서브쿼리의 결과 중 하나라도 같은 것이 있으면 참
서브 쿼리 - 예제
팀A 소속인 회원 조회
select m from Member m where exists (select t from m.team t where t.name = '팀A')
전체 상품 각각의 재고보다 주문량이 많은 주문들
select o from Order o where o.orderAmount > ALL(select p.stockAmount from Product p)
어떤 팀이든 팀에 소속된 회원
select m from Member m where m.team = ANY(select t from Team t)
JPA 서브 쿼리의 한계
- JPA는 WHERE, HAVING 절에서만 서브 쿼리 사용 가능
- SELECT 절도 가능(하이버네이트에서 지원)
- FROM 절의 서브 쿼리는 현재 JPQL에서 불가능
- 조인으로 풀 수 있으면 풀어서 해결
'JPA' 카테고리의 다른 글
[JPA] JPQL(Java Persistence Query Language) 문법(1) (0) | 2020.04.30 |
---|---|
[JPA] 값 타입 컬렉션 (0) | 2020.04.26 |
[JPA] 값타입과 불변 객체 (0) | 2020.04.26 |
[JPA] 임베디드 타입(복합 값 타입) (0) | 2020.04.26 |
[JPA] 고아객체 (0) | 2020.04.22 |