JPQL이란?
JPA가 제공하는 SQL을 추상화한 객체 지향 쿼리 언어
SQL을 추상화했기 때문에 특정 데이터베이스 SQL에 의존하지 않는다.
JPQL은 결국 SQL로 변환된다.
JPQL과 SQL의 차이점
JPQL은 엔티티 객체를 대상으로 쿼리문이 짜여진다.
SQL은 데이터베이스 테이블을 대상으로 쿼리문이 짜여진다.
JPA가 제공하는 다양한 쿼리 방법
- JPQL
- JPA Criteria
- 자바코드로 JPQL 작성 가능
- JPQL 빌더 역할
- JPA의 공식 기능
- 복잡하고 실용성이 없음. -> 코드가 너무 길어짐
- QueryDSL 사용 권장
- QueryDSL
- 자바코드로 JPQL 작성 가능
- JPQL 빌더 역할
- 컴파일 시점에 문법 오류를 찾을 수 있음
- 동적쿼리 작성이 편리함
- 단순하고 쉬움
- 실무 사용 권장
- 네이티브 SQL
- SQL을 직접 사용하는 기능
- JPQL로 해결할 수 없는, 특정 데이터베이스에 의존적인 기능을 사용하고 싶을 때
- 예: 오라클 CONNECTED BY (이건 내가 안사용해봐서 모르겠지만 오라클의 DECODE랑 비슷한 느낌인 듯 하다)
- JDBC API 직접 사용, MyBatis, SpringJdbcTemplate 결합
- JPA를 사용하면서도 JDBC 직접 사용이나 MyBatis를 함께 결합해서 사용할 수 있다.
- 영속성 컨텍스트를 수동으로 강제 플러시를 해줄 필요가 있다.
JPQL 문법
select m from Member as m where m.age > 18
엔티티와 속성은 대소문자를 구분한다. 엔티티: Member, 속성: age
JPQL 키워드는 대소문자 구분X (SELECT, FROM, where...)
테이블 명과 엔티티 명은 다를 수 있음.
JPQL에서 별칭은 필수이다.
as 는 생략 가능하다. -> select m from Member m where m.age > 18
TypeQuery VS Query
TypeQuery: 반환 타입이 명확할 때 사용
Query: 반환 타입이 명확하지 않을 때 사용
TypedQuery<Member> query = em.createQuery("SELECT m FROM Member m", Member.class);
Query query = em.createQuery("SELECT m.username, m.age from Member m");
결과 조회
query.getResultList();
-> 결과가 하나 이상일 때, 리스트 반환. 없으면 빈 리스트 반환
query.getSingleResult();
-> 결과가 정확히 하나일 때, 단일 객체 반환. 없으면 javax.persistence.NoResultException 발생.
-> 둘 이상이면 javax.persistence.NonUniqueResultException 발생.
프로젝션
SELECT 절에 조회할 대상을 지정하는 것
대상: 엔티티, 임베디드 타입, 스칼라 타입
DISTINCT로 중복을 제거한다.
스칼라 타입이란?
숫자, 문자 등 기본 데이터 타입을 말한다.
SELECT m FROM Member m -> 엔티티 프로젝션
SELECT m.team FROM Member m -> 엔티티 프로젝션
SELECT m.address FROM Member m -> 임베디드 타입 프로젝션
SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션
여러 스칼라 타입 한번에 조회할 때
- Query 타입으로 조회
- Object[] 타입으로 조회
- new 명령어로 조회
- 단순값을 DTO로 바로 조회
- SELECT new tripdream.common.dto.MemberDTO(m.username, m.age) FROM Member m
- 패키지 명을 포함한 전체 클래스 명을 입력해야 함.
- 순서와 타입이 일치하는 생성자가 필요하다.
조인의 종류
- 내부 조인
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
JPA 서브 쿼리 한계
- WHERE, HAVING 절에서만 서브 쿼리를 사용할 수 있다.
- SELECT 절은 하이버네이트에서 지원한다.
- FROM 절의 서브 쿼리는 현재 JPQL에서 불가능하다.
- 조인으로 풀어서 해결해야 한다.
'Spring > 이론' 카테고리의 다른 글
[JPA] JPQL fetch join 페치 조인 (0) | 2023.08.02 |
---|---|
[JPA] JPQL 경로 표현식 (0) | 2023.08.02 |
JPA - 값 타입 (0) | 2023.07.07 |
Spring Security 동작 원리 / 필터 순서 (0) | 2023.07.05 |
JPA - 영속성 전이, 고아 객체 (0) | 2023.06.29 |