📌 소개
- 가장 단순한 조회 방법
- EntityManager.find()
- 객체 그래프 탐색(a.getB().getC())
- 나이가 18살 이상인 회원을 모두 검색하고 싶다면?
JPQL
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- 문제는 검색 쿼리
- 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
- 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
- JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
- SQL과 문법 유사,SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
- JPQL은 엔티티 객체를 대상으로 쿼리
- SQL은 데이터베이스 테이블을 대상으로 쿼리
- JPQL을 짜면 SQL로 번역되어 실행이 된다!
📌 기본 문법과 쿼리 API
- JPQL은 객체지향 쿼리 언어다. 따라서 테이블을 대상으로 쿼리하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
- JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다.
- JPQL은 결국 SQL로 변환된다.
📌 JPQL 문법
select
COUNT(m), //회원수
SUM(m.age), //나이 합
AVG(m.age), //평균 나이
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
<집합과 정렬>
- GROUP BY, HAVING
- ORDER BY
- select m from Member as m where m.age > 18 ( Member가 엔티티!!! )
- 엔티티와 속성은 대소문자 구분O (Member, age)
- JPQL 키워드는 대소문자 구분X (SELECT, FROM, where)
- 엔티티 이름 사용, 테이블 이름이 아님(Member)
- 별칭은 필수(m) (as는 생략가능)
📌 TypeQuery, Query
- TypeQuery: 반환 타입이 명확할 때 사용
- Query: 반환 타입이 명확하지 않을 때 사용
//타입이 명확
TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
//username만 하면 타입을 String으로 잡으면 됨.
Query query2 = em.createQuery("select m.username from Member m", String.class);
//But username과 age를 함께 조회하므로 타입이 불명확
Query query3 = em.createQuery("select m.username, m.age from Member m");
📌 결과 조회 API
- query.getResultList(): 결과가 하나 이상일 때, 리스트 반환
- 결과가 없으면 빈 리스트 반환 (null pointer exception에 대한 걱정 X)
- query.getSingleResult(): 결과가 정확히 하나, 단일 객체 반환
- 결과가 없으면: javax.persistence.NoResultException
- 둘 이상이면: javax.persistence.NonUniqueResultException
📌 파라미터 바인딩 - 이름 기준, 위치 기준
<이름 기준>
Member result = em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "member1")
.getSingleResult();
System.out.println("result = " + result);
<위치 기준>
SELECT m FROM Member m where m.username=?1
query.setParameter(1, usernameParam);
되도록이면 위치 기준으로는 쓰지 말고 이름 기준으로만 쓰기!
위치는 중간에 뭐가 추가되고 이럴 경우 다 밀리기 때문.
반응형