JPQL

JPQL을 한마디로 정의하면 객체 지향 SQL

테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리

//검색
 String jpql = "select m From Member m where m.name like ‘%hello%'";
 List<Member> result = em.createQuery(jpql, Member.class)
	 .getResultList();

NATIVE QUERY

JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능

JPQL 문법

하이버네이트6 부터는 FROM 절의 서브쿼리를 지원합니다

별칭은 필수(m) (as는 생략가능)
엔티티 이름 사용, 테이블 이름이 아님(Member)

TypedQuery<Member> query =
	 em.createQuery("SELECT m FROM Member m", Member.class); 

Query query =
	 em.createQuery("SELECT m.username, m.age from Member m"); 
	 
SELECT m FROM Member m where m.username=:**username**
	query.setParameter("username", usernameParam);
	
SELECT m FROM Member m where m.username=?1
	query.setParameter(1, usernameParam);

// 프로젝션 - 여러 값 조회
1. Query 타입으로 조회
2. Object[] 타입으로 조회
3. new 명령어로 조회
	• 단순 값을 DTO로 바로 조회
		- SELECT new jpabook.jpql.UserDTO(m.username, m.age) FROM Member m
	• 패키지 명을 포함한 전체 클래스 명 입력
	• 순서와 타입이 일치하는 생성자 필요

 //페이징 쿼리
 String jpql = "select m from Member m order by m.name desc";
 List<Member> resultList = em.createQuery(jpql, Member.class)
		 .setFirstResult(10) // 조회 시작 위치
		 .setMaxResults(20) // 조회할 데이터 수 
		 .getResultList();	
		 
// 조인
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 // 세타 조인 

// 서브 쿼리
//나이가 평균보다 많은 회원
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 

// case
COALESCE: 하나씩 조회해서 null이 아니면 반환
NULLIF: 두 값이 같으면 null 반환, 다르면 첫번째 값 반환

// 경로 표현식
select m.username -> 상태 필드
	 from Member m
		 join m.team t -> 단일 값 연관 필드
		 join m.orders o -> 컬렉션 값 연관 필드
where t.name = '팀A' 
단일 값 연관 경로: 묵시적 내부 조인(inner join) 발생, 탐색O
컬렉션 값 연관 경로: 묵시적 내부 조인 발생, 탐색X

명시적 조인, 묵시적 조인

명시적 조인: join 키워드 직접 사용

select m from Member m join m.team t

묵시적 조인: 경로 표현식에 의해 묵시적으로 SQL 조인 발생 (내부 조인만 가능)

select m.team from Member m

가급적 묵시적 조인 대신에 명시적 조인 사용

Distinct

하이버네이트6 부터는 DISTINCT 명령어를 사용하지 않아도 애플리케이션에서 중복 제거가 자동으로 적용됩니다