- JPA는 다양한 쿼리 방법을 지원한다.
- JPQL
- JPA criteria
- QueryDSL
- 네이티브 SQL
- JDBC 직접 사용, Mybatis, SpringJDBCTemplate 함께 사용
JPQL
- JPA를 사용하면 엔티티 객체를 중심으로 개발한다.
- 문제는 검색 쿼리이다.
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색한다.
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다.
JPQL이란?
JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다.
SQL과 문법이 유사하며, SELECT, FROM, WHERE, GROUP BY, HAVING JOIN을 지원한다.
JPQL은 엔티티 객체를 대상으로 쿼리를 한다.
SQL은 데이터베이스 테이블을 대상으로 쿼리를 한다.
위의 코드와 같이 EntityManger를 통해서 createQuery를 생성할 수 있다. 쿼리를 보면 SQL과 매우 유사하며 여기서의 Member는 테이블이 아닌 엔티티 클래스를 가리킨다.
- JPQL 문법
ex)
select m from Member as m where m.age <18
- 엔티티와 속성은 대소문자 구분 O(Member, age)
- JQPL 키워드는 대소문자 구분 x(SELECT, FROM, where)
- 테이블 이름이 아닌 엔티티 이름 사용(Member)
- 별칭은 필수(m)(as는 생략 가능)
위의 코드와 같이 member에 값을 세팅해주고, em.clear()로 영속성컨텍스트를 초기화시킨 후, em.createQuery로 Member엔티티의 를 가져와 값을 변경시켰는데 위와 같이 update쿼리가 나가게 된 걸 볼 수 있다. 이 이유는 엔티티 프로젝션(SELECT)은 영속성컨텍스트를 관리해주기 때문이다.
- 페이징 API
JPA는 페이징을 다음 두 API로 추상화한다.
- setFirstResult(int startPosition): 조회 시작 위치 0부터 시작
- setMaxResult(int maxResult) : 조회할 데이터 수
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
위의 코드를 보면 jpql로 Member엔티티의 age를 내림차순으로 조회하였고, setFirstResult(1) 1번째 인덱스부터 setMaxResults(10) 10개의 값을 조회해서 getResultList() 리스트로 반환하였다.
- 조인
JPA에서는 객체의 연관관계로 조인을 하여 테이블의 FK와 PK를 찾는다.
위의 코드와 같은 경우 실행을 하면 Exception이 터지게 된다. 그 이유는 일반적인 연관관계가 없는 쿼리에서는 ON절이 필수로 들어가야 한다. 하지만 다음 아래와 같이 바꾸어보면 결과가 다르다.
위의 코드와 같이 객체의 연관관계로 join쿼리를 하면 위의 쿼리 결과와 같이 JPA가 알아서 FK와 PK를 참고하여 ON절 추가해주게 된다.
- JPA 서브 쿼리 한계
- JPA는 WHERE, HAVING 절에서만 서브 쿼리 사용 가능
- SELECT절도 가능하다(하이버네이트에서 지원)
- FROM 절의 서브 쿼리는 현재 JQPL에서는 불가능
'JPA' 카테고리의 다른 글
값 타입 (0) | 2021.10.12 |
---|---|
프록시, 즉시 로딩과 지연 로딩 (0) | 2021.10.11 |
고급 매핑 (0) | 2021.10.10 |
다양한 연관관계 매핑 (0) | 2021.10.09 |
연관관계 매핑 (0) | 2021.10.08 |