JPA - 객체지향 쿼리 언어1
JPQL - 대부분은 이것으로 해결된다.
QueryDSL
위에 두개는 자바코드로 짜서 JPQL을 만들어주는 것
네이티브 SQL - 가끔씩 안될때는 이걸 쓴다.
JPQL
- 가장 단순한 조회 방법
- EntityManger.find()
- 객체 크래프 탐색(a.getB().getC())
- 나이가 18살 이상인 회원을 모두 조회하고 싶다면?
- JPA를 사용하면 엔티티 객체 중심으로 개발
- 문제는 검색 쿼리
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불려오려면 결국 검색 조건이 포함된 SQL이 필요
- JPA는 SQL을 추상화한 JPQL이라는 객체지향쿼리 언어 제공
- SQL과 문법 유사 Select from where group by having join 지원
- JPQL은 엔티티객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
JPQL문법에서 select m from Member m where m.username like '%kim%';
여기서 m이라고 하면은 Member Entity객체를 의미하고 select 뒤에 있는 m은 member자체를 가르킨다.
member자체를 조회하란 뜻
테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
SQL을 추상화해서 특정 데이터베이스 SQL에 의존x
JPQL을 한마디로 정의하면 객체 지향 SQL
QueryDSL 소개
- 문자가 아닌 자바코드로 JPQL을 작성할 수 있음
- JPQL 빌더 역할
- 컴파일 시점에 문법 오류를 찾을 수 있음
- 동적쿼리 작성 편리함
- 단순하고 쉬움
- 실무 사용 권장
JPA를 사용하면서 JDBC커넥션을 직접 사용하거나, 스프링 Jdbctemplate, 마이바티스등을 함께 사용 가능
단 영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요
예) JPA 우회해서 SQL을 실행하기 직전에 영속성 컨텍스트 수동 플러시
JPQL (JAVA Persistence Query Language)
JPQL소개
- JPQL은 객체지향 쿼리 언어다. 따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
- JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다
- JPQL은 결국 SQL로 변환된다.
별칭은 필수(m)이다.
query.getResultList(): 결과가 하나 이상일 때, 리스트 반환
결과가 없으면 빈 리스트 반환
query.getStringResult(): 결과가 정확히 하나, 단일 객체 반환
결과가 없으면: javax.persistence.NoResultException
둘 이상이면: javax.persistence.NonUniqueResultException
프로젝션
select 절에 조회할 대상을 지정하는 것
프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자등 기본 데이터 타입_
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 ->
프로젝션 여러 값 조회
- select m.username. m.age from ember m
- 1. query 타입으로 조회
- 2. object[] 타입으로 조회
- 3. new 명령으로 조회
- 단순 값을 DTO로 바로 조회
- select new jpabook.jpql.UserDTO(m.username, m.age) from member m
- 패키지 명을 포함한 전체 클래스 명 입력
- 순서와 타입이 일치하는 생성자 필요
페이징 API
- JPA는 페이징 다음 두 API로 추상화
- setFIrstResult(int startPosition): 조회 시작 위치(0부터 시작)
- setMaxResults(int maxResult): 조회할 데이터 수
조인
내부조인
select m from Member m inner join m.team t
외부조인
세타조인
서브쿼리
서브로 쿼리를 만들수있는 것
나이가 평균보다 많은 회원
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
JPA 서브 쿼리 한계
JPA는 where, having 절에서만 서브 쿼리 사용가능
select 절도 가능 (라이버네이트에서 지원)
FROM 절의 서브 쿼리는 현재 JPQL에서 불가능
조인으로 풀 수 있으면 풀어서 해결