[JPQL] 객체지향 쿼리 언어 - JPQL

형이·2023년 10월 13일

Spring

목록 보기
21/21
post-thumbnail

📝 JPQL

🖥️ 1. 객체지향 쿼리 언어 (JPQL)

1-1. JPA는 다양한 쿼리 방법을 지원

  • JPQL

  • QueryDSL

  • JPA Criteria

  • 네이티브 SQL

  • JDBC API 직접 사용

  • MyBatis

  • SpringJdbcTemplate

1-2. JPQL 소개

  • 단순한 조회 : EntityManager.find()

    	예시) 나이가 18살 이상인 회원을 모두 검색하고 싶다면?

1-3. JPQL이란

Java Persistence Query Language

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 문제는 검색 쿼리
  • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
  • 모든 DB데이터를 객체로 변환해서 검색하는 것은 불가능
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공
  • SQL 문법이 유사, select / from / where / group by / having / join 지원
  • JPQL 엔티티 객체를 대상으로 쿼리를 작성
  • SQL은 데이터베이스 테이블을 대상으로 쿼리를 작성
  • JPQL을 한 마디로 정의하면 '객체 지향 SQL'

1-4. JPQL 문법

  • 대소문자 구분
    - 엔티티와 속성은 대소문자 구분한다.
    - JPQL 키워드는 구분하지 않는다.
  • 엔티티 이름
    - 테이블명 대신 엔티티명을 사용한다.
    - @Entity(name = "...") // 엔티티명 지정하는 방법
    - 엔티티명을 지정하지 않을 시에는 클래스명을 기본 값으로 사용 (추천하는 방법)
  • 별칭은 필수
    - JPQL은 별칭 필수
    - AS는 생략 가능
  • select m from Member as m where m.age > 18
    - Member : 엔티티 속성, 대소문자 구분
    - java 클래스는 대소문자를 구분하기 때문
    - 엔티티 이름 사용, 테이블 이름이 아니다.
    - 엔티티 이름을 @Entity(name = "mm")으로 수정 시, JPQL에서도 mm으로 써야 한다. (하지만 이렇게 쓰지 않음)
    - JPQL 키워드 : select, from, where 대소문자 구분 안 함

1-5. 집합과 정렬

select
	count(m),	// 회원수
	sum(m.age),	// 나이 합
	avg(m.age),	// 평균 나이
	max(m.age),	// 최대 나이
	min(m.age)	// 최소 나이
from Member m
  • group by, having
  • order by

1-6. TypeQuery, Query

  • TypeQuery : 반환 타입이 명확할 때 사용
	TypeQuery<Member> query = em.createQuery("select m from Member m", Member.class);
  • Query : 반환 타입이 명확하지 않을 때 사용
	Query query = em.createQuery("select m.username, m.age from Member m");

1-7. 결과 조회

  • query.getResultList() : 결과가 하나 이상일 때, 리스트 반환

    ✔️ 결과가 없으면 빈 리스트 반환

    ✔️ 빈 collection이 반환되기 때문에 NullPointException에 대한 걱정은 안 해도 된다.

  • query.getSingleResult() : 결과가 정확히 하나(조심!), 단일 객체 반환

 ✔️ 결과가 없으면 : NoResultException

 ✔️ 결과가 둘 이상이면 : NoUniqueResultException

1-8. 파라미터 바인딩

  • 이름 기준
select m from Member m where m.username = :username
query.setParameter("username", usernameParam);
  • 위치 기준 (쓰지 말 것!)
select m from Member m where m.username = ?1
query.setParameter(1, usernameParam);

1-9. 프로젝션

  • select 절에 조회할 대상을 지정하는 것
  • 프로젝션 대상 : 엔티티, 임베디드 타입, 스칼라 타입 (숫자, 문자 등 기본 데이터 타입)
  • select m from Member m : Member 엔티티 조회
  • select m.team from Member m : Member와 관련된 team을 가지고 온다.
  • select m.address from Member m : 임베디드 타입을 가지고 온다.
  • select m.username, m.age from Member m : 스칼라 타입 프로젝트

1-10. 여러 타입으로 조회

** JpaMain04

1-11. 페이징 API

  • JPA는 페이지를 다음 두 API로 추상화
  • setFirstResult(int startPoint) : 조회 시작 위치 (0부터 시작)
  • setMaxResults(int maxResult) : 조회할 데이터 수
-> 몇 번째부터 몇 건을 가지고 올래?

1-12. 조인

  • 문법이 객체 스타일로 나간다.
  • 내부조인

    	elect m from Member m (inner) join m.team t
  • 외부조인

    	select m from Member m left (outer) join m.team t

1-13. 서브쿼리

  • From절의 서브쿼리는 현재 JPQL에서는 불가능하다. 조인으로 풀 수 있으면 풀어서 해결

0개의 댓글