[3] JPA 프로그래밍 (15) - JPQL(객체지향 쿼리 언어) 3 (Named 쿼리 / 벌크연산)

김정욱·2021년 3월 11일
0

[3] JPA 프로그래밍

목록 보기
15/15
post-thumbnail

다형성 쿼리

  • 다형성 관계에 있는 객체를 대상으로 JPA가 지원하는 기능
    • TYPE
      : 조회 대상을 특정 자식으로 한정
      ex) Item중에 Book,Movie를 조회해라
    • TREAT
      : 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용
/* TYPE - 조회 대상을 특정 자식으로 한정 */
[JPQL]
select i from Item i
where TYPE(i) IN (Book, Movie)

[SQL]
select i from i
where i DTYPE in ('B', 'M') // DTYPE 칼럼으로 변환해서 in으로 검사

=======================================
/* TREAT - 자바의 타입 캐스팅 원리와 유사 */
[JPQL]
select i from Item i
where treat(i as Book).author = 'kim' // author는 Book에만 있는 컬럼

[SQL]
select i.* from Item as i
where i.DTYPE = 'B' and i.author = 'kim'

엔티티 직접 사용

  • JPQL에서 엔티티 자체직접 사용하면 SQL에서 해당 엔티티의 기본키 값(PK)을 사용
[JPQL]
select count(m.id) from Member m // 엔티티의 기본키를 직접 넣음
select count(m) from Member m // 엔티티 자체를 넣음 - 위와 동일!

[SQL]
select count(m.id) from Member as m
  • 연관관계가 있는 객체들은외래키(FK)로 사용됨
[JPQL]
select m from Member m where m.team=:team 
// :team은 파라미터이며 실제 코드에서 team객체를 넘김

[SQL]
select m.* from Member as m where m.team_id=?

Named 쿼리

[ 설명 ]

  • 미리 정의해서 이름을 부여해두고 사용하는 정적 JPQL
  • 어노테이션 or XML에 정의하여 사용
  • 애플리케이션 로딩 시점초기화 후 재사용
    : 애플리케이션 로딩 시점에 Named쿼리를 파싱해서 캐시에 들고있다가 필요시 사용
  • 애플리케이션 로딩 시점에 쿼리를 검증
    : 애플리케이션 로딩 시점에 오타가 있을 경우 문법 검사를 해서 컴파일 오류를 냄!

[ 예시 ]

  • 호출할 name을 지정할 때 관례엔티티.함수이름 이렇게 많이 사용
  • 스프링 데이터 JPA에서 @Query()로 지원

[ XML 정의 ]

  • XML파일정의할 수도 있다
  • 어노테이션 지정보다 XML 파일로 지정하는 것이 우선권을 가짐

벌크 연산

[ 설명 ]

  • 벌크연산 ?
    : pk를 정해서 하나에 대해 실행하는 update, delete를 제외한 모든 연산
    (여러개를 대상으로 진행하는 update, delete 쿼리)
  • 필요성
    : JPA 더티 체킹으로 실행하려면 많은 SQL이 수행될때 하나의 쿼리로 변환
    ex) 재고가 10개 미만인 모든 상품의 가격을 10% 상승하는 경우
    • 더티 체킹(Dirty Checking)
      : 트랜잭션이 끝나는 시점에 변화가 있는 Entity스냅샷과 비교해서 변화가 있는 경우 자동으로 DB에 변경하는 쿼리를 날려주는 것
  • 사용 방법
    • 쿼리를 작성 후 query.executeUpdate()로 실행
    • 반환 값영향 받은 엔티티의 수

[ 예시 ]


[ 주의할 점 ]

  • UPDATEDELETE 만 공식 지원
  • HibernateINSERT도 추가 지원
  • 벌크 연산영속성 컨텍스트를 무시하고 DB직접 접근한다! (중요)
    (영속성 컨텍스트를 무시하기 때문에 로직에서 오류가 날 수 있음)
  • 벌크 연산을 안전하게 사용하는 방법 2가지
    • 벌크 연산 먼저 실행
      : 먼저 수행하면 영속성 컨텍스트와 상관 없어짐
    • 벌크 연산 수행 후 영속성 컨텍스트 초기화
      : 중간에 벌크 연산을 사용하면 영속성 컨텍스트데이터 동기화가 되지 않아서 문제가 발생할 수 있다
          --> 중간에 사용시 반드시 영속성 컨텍스트초기화 한 후 사용
                 (JPQL 날리면 자동 flush되지만, clear는 안되니까 clear는 해줘야함!)
profile
Developer & PhotoGrapher

0개의 댓글