[JPA 기본] - 객체지향 쿼리 언어(JPQL)

Sunwu Park·2024년 1월 2일

Inflearn - Spring

목록 보기
18/21

JPQL

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 테이블이 아닌 엔티티 객체를 대상으로 검색
  • JPA는 SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어 제공

Criteria

= 자바 코드로 JPQL작성, JPQL 빌더

  • 하지만 너무 복잡하고 실용성이 없다

QueryDSL

  • 자바코드로 JPQL작성, JPQL빌더, 컴파일시 문법 오류 찾기 가능, 동적쿼리 편리
  • 단순하고 쉽다

Native SQL

  • JPA가 제공하는 SQL을 직접 사용
  • 특정 데이터베이스에 의존적인 기능

  • 영속성 컨텍스트를 적절한 시점에 강제로 플러시 해야한다

JPQL

  • 객체지향 쿼리 언어, 엔티티 대상으로 쿼리
  • 엔티티와 속성은 대소문자 구분 O
  • JPQL 키워드는 대소문자 구분X(SELECT, where)
  • 엔티티 이름을 사용한다
  • 별칭은 필수이다

TypeQuery, Query

  • TypeQuery: 반환 타입이 명확할때 사용
  • Query: 반환 타입이 명확하지 않을때

결과 조회 API

  • query.getResultList(): 결과가 하나 이상일때 리스트 반환
    - 없으면 빈 리스트
  • query.getSingleResult(): 결과가 정확히 하나,단일 객체 반환
    - 없으면, NoREsultException
    • 둘 이상, NonUniqueResultException
SELECT m FROM Member m where m.username=:username

query.setParameter("username", usernameParam);

Paging API

  • setFirstResult: 조회 시작 위치
  • setMaxResults: 조회할 데이터 수
//페이징 쿼리
 String jpql = "select m from Member m order by m.name desc";
 List<Member> resultList = em.createQuery(jpql, Member.class)
 .setFirstResult(10)
 .setMaxResults(20)
 .getResultList();

On 절 조인

  • 조인 대상 필터링
    - JPQL
    SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'A'
    SQL:
    SELECT m., t. FROM
    Member m LEFT JOIN Team t ON m.TEAM_ID = t.id and t.name = 'A'

  • 연관관계 없는 엔티티 외부 조인
    - JPQL:
    SELECT m, t FROM
    Member m LEFT JOIN Team t on m.username = t.name

    • SQL:
      SELECT m., t. FROM
      Member m LEFT JOIN Team t ON m.username = t.name

Coalesce, Nullif

  • Coalesce: 하나씩 조회해서 null이 아니면 반환
  • Nullif: 두 값이 같으면 null 반환, 다르게 첫번째 값 반환

경로표현식

  • 상태필드: 단순히 값을 저장하기 위한 필드/ 경로 탐색의 끝,
  • 연관 필드: 연관관계를 위한 필드
    - 단일 값 연관 필드: (묵시적 내부 조인 발생, 탐색 O)
    - @ManyToOne, @OneToOne, 대상이 엔티티
    • 컬렉션 값 연관 필드: (묵시적 내부 조인 발생, 탐색 X)
      • @OneToMany, @ManyToMany, 대상이 컬렉션

Fetch Join

  • JPQL 에서 성능 최적화를 위해 제공하는 기능
  • SQL한번에 조회

Fetch Join 특징/한계

  • 별칭을 줄 수 없다
  • 둘 이상의 컬렉션은 페치 조인 할 수 없다
  • 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.
  • 한번으로 조회하므로 성능 최적화한다/ 글로벌 로딩 전략보다 우선
  • 객체 그래프 유지할 때 사용하면 효과적

Named 쿼리 - 정적 쿼리

  • 미리 정의해서 이름을 부여해두고 사용하는 JPQL
  • 애플리케이션 로딩 시점에 쿼리를 검증

벌크 연산

  • 쿼리 한번으로 여러 테이블 로우 변경
  • execute Update() 결과는 영향받은 엔티티 수 반환
  • UPDATE, DELETE, INSERT 지원

=> 영속성 컨텍스트 무시, 데이터베이스에 직접 쿼리

  • 수행후 영속성 컨텍스트 초기화한다

0개의 댓글