본 포스팅은 인프런 - 자바 ORM 표준 JPA 프로그래밍 (기본편) 을 강의를 바탕으로 공부하고 정리한 글입니다.
JPQL이란?
- 객체지향 쿼리 언어
- 테이블을 대상으로 쿼리하는 것이 아닌 엔티티 객체를 대상으로 쿼리한다.
- JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다는 장점이 있다.
- JPQL도 결국 SQL로 변환되어 실행된다.
JPQL 기본 문법
select, update, delete
select m from Member as m where m.age > 18
- SQL 문법과 동일하다.
- 엔티티, 속성은 대소문자를 구분한다. (Member, age)
- JPQL 키워드는 대소문자를 구분하지 않는다. (SELECT, FROM, WHERE)
- 테이블 이름이 아닌 엔티티 이름을 사용한다.
- 별칭을 필수로 사용한다. (m) (as 생략 가능)
집합과 정렬
select
count(m), -- 회원수
sum(m.age), -- 나이합
avg(m.age), -- 평균 나이
max(m.age), -- 최대 나이
min(m.age) -- 최소 나이
from Member m
- group by, having, order by 모두 동일하게 사용
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"); // String, int 둘 중 어떤 타입으로 지정 불가능
- TypeQuery : 반환 타입이 명확할 때 사용
- Query : 반환 타입이 명확하지 않을 때 사용
결과 조회 API
List<Member> result = em.createQuery("select m from Member m", Member.class)
.getResultList();
Member result = em.createQuery("select m from Member m where m.id=1", Member.class)
.getSingleResult();
- query.getResultList()
- 결과가 1개 이상일 때 사용
- 리스트 반환
- 결과가 없으면 빈 리스트를 반환
- query.getSingleResult()
- 결과가 정확히 1개일 때 사용
- 단일 객체 반환
- 결과가 없으면 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();
- query.setParameter() : ":parameter"로 기준을 지정한뒤, setParameter() 메서드 체이닝으로 값을 지정
여러 값 조회
// 방법1
List result = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object o = result.get(0);
Object[] ol = (Object[]) o;
// 방법2
List<Object[]> result = em.createQuery("select m.username, m.age from Member m")
.getResultList();
Object[] ol = result.get(0);
// 방법3
List<MemberDto> result = em.createQuery("select new jpql.MemberDto(m.username, m.age) from Member m", MemberDto.class)
.getResultList();
public class MemberDto {
private String username;
private int age;
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
- Query 타입으로 조회
- Query[] 타입으로 조회
- new 명령어로 조회
- 단순 값을 DTO로 바로 조회
- ex) select new jpa.book.jpql.UserDto(m.username, m.age) from Member m
- 패키지 명을 포함한 전체 클래스명을 입력해줘야 한다.
- 순서와 타입이 일치하는 생성자가 필요하다.
프로젝션
-- 엔티티 프로젝션
select m from Member m
select m.team from Member m
-- 임베디드 타입 프로젝션
select m.address form member m
-- 스칼라 타입 프로젝션
select distinct m.username, m.age from Member m
- 프로젝션은 SELECT 절에서 조회할 대상을 지정하는 것을 말한다.
- 프로젝션의 대상 : 엔티티, 임베디드 타입, 스칼라 타입(숫자, 문자 등 기본 데이터 타입)
- DISTINCT로 중복을 제거할 수 있다.
- 엔티티 프로젝션으로 조회된 모든 엔티티는 영속성 컨텍스트로 관리된다.
조건식 (CASE 식)
/* 기본 CASE 식 */
select
case when m.age <= 10 then '학생요금'
when m.age >= 60 then '경로요금'
else '일반요금'
end
from Member m
/* 단순 CASE 식 */
select
case t.name
when '팀A' then '인센티브110%'
when '팀B' then '인센티브120%'
else '인센티브105%'
end
from Team t
'🌱 Spring > JPA' 카테고리의 다른 글
[JPA] OSIV (0) | 2022.12.27 |
---|---|
[JPA] JPQL : 서브 쿼리 (0) | 2022.11.06 |
[JPA] JPQL : 조인 (0) | 2022.11.04 |
[JPA] JPQL : 페이징 (0) | 2022.11.03 |
[JPA] JPA가 지원하는 쿼리 방법 (JPQL, Criteria, QueryDsl) (0) | 2022.10.29 |
[JPA] 값 타입 (0) | 2022.10.19 |
[JPA] 영속성 전이(CASECADE)와 고아 객체 (0) | 2022.10.18 |
[JPA] 즉시 로딩(LAZY)과 지연 로딩(EAGER) (0) | 2022.10.18 |