jpa는 다양한 쿼리 방법을 지원한다. jpql,jpa criteria,querydsl,native sql, jdbc api직접사용,mybatis 등등 많다
JPA를 사용하면 엔티티 객체를 중심으로 개발할 수 있다. 문제는 검색 쿼리. 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색.
jpql과 실행된 sql 이다.
18살 이상의 회원을 조회하는 쿼리.
1.조인
내부 조인: 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
2.ON절
1.조인 대상 필터링
예) 회원과 팀을 조인하면서, 팀 이름이 A인 팀만 조인
JPQL: SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'A'
SQL:
SELECT m.*, t.*
FROM Member m LEFT JOIN Team t
ON m.TEAM_ID=t.id and t.name='A'
2.연관관계 없는 엔티티 외부 조인
예) 회원의 이름과 팀의 이름이 같은 대상 외부 조인
JPQL: SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
SQL:
SELECT m.*, t.*
FROM Member m LEFT JOIN Team t
ON m.username = t.name
나이가 평균보다 많은 회원
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
팀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)
서브쿼리의 한계 : FROM 절의 서브 쿼리는 현재 JPQL에서 불가능, 조인으로 풀 수 있으면 풀어서 해결
JPQL에서 성능 최적화를 위해 제공하는 기능이다.
연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회 하는 기능.
join fetch 명령어 사용
페치 조인 ::= [ LEFT [OUTER] | INNER ] JOIN FETCH 조인경로
엔티티 패치 조인
• 회원을 조회하면서 연관된 팀도 함께 조회(SQL 한 번에)
• SQL을 보면 회원 뿐만 아니라 팀(T.*)도 함께 SELECT
• [JPQL] : select m from Member m join fetch m.team
• [SQL] : SELECT M.*, T.*
FROM MEMBER M INNER JOIN TEAM T
ON M.TEAM_ID=T.ID
member와 team이 다대일 일대다 연관관계라고 가정해보자. 원래 jpa 일대다 다대일 등 연관관계에서는 지연로딩(LAZY) 방식이다.또한 일반 조인 실행시 연관된 엔티티를 함께 조회하지 않는다. 그렇기 때문에 member를 조회하는 쿼리를 날리면 team의 proxy객체가 호출되어서 team의 프로퍼티를 조회하게 되면 쿼리가 한번 더 나가게 되서 흔히 말하는 N+1 문제가 발생한다. 그렇기 때문에 fetch join을 이용하게되면 member와 team의 엔티티객체에 한번에 select 쿼리를 날려member.getTeamName() 이런식의 코드를 짜도 프록시 객체가 아닌 진짜 객체가 조회된다. 쿼리 한 번에 다 해결할 수 있다.
패치조인 일반조인 차이점
1.페치 조인을 사용할 때만 연관된 엔티티도 함께 조회(즉시 로딩)
2.페치 조인은 객체 그래프를 SQL 한번에 조회하는 개념
SQL의 DISTINCT는 중복된 결과를 제거하는 명령이다.
아래 방식 처럼 사용한다.
select distinct t
from Team t join fetch t.members
where t.name = ‘팀A’