객체지향 쿼리 언어(3)

Jeongyeon Kim·2023년 2월 7일
0

JPA

목록 보기
11/11
post-thumbnail

5. 네이티브 SQL

  • 특정 데이터베이스에 종속적인 기능을 지원하는 방법

    • 특정 데이터베이스만 사용하는 함수
    • 특정 데이터베이스만 지원하는 SQL 쿼리 힌트
    • 인라인 뷰(From 절에서 사용하는 서브 쿼리), UNION, INTERSECT
    • 스토어 프로시저
    • 특정 데이터베이스만 지원하는 문법
  • 네이티브 SQL을 사용하면 엔티티를 조회할 수 있고 JPA가 지원하는 영속성 컨텍스트의 기능을 그대로 사용할 수 있음

  • JDBC API를 직접 사용하면 데이터의 나열을 조회할 뿐

네이티브 SQL 사용

엔티티 조회

  • em.createNativeQuery(SQL, 결과 클래스)
  • 실제 데이터베이스 SQL 사용
  • 위치기반 파라미터만 지원(하이버네이트는 이름 기반 파라미터 사용 가능)
  • 조회한 엔티티 영속성 컨텍스트에서 관리됨

값 조회

  • em.createNativeQuery(SQL)
  • 조회할 값들을 Object[]에 담아서 반환
  • 스칼라 값을 조회했으므로 영속성 컨텍스트가 관리 X

결과 매핑 사용

  • @SqlResultSetMapping
  • @EntityResult
  • @FieldResult
  • @ColumnResult

Named 네이티브 SQL

  • createNamedQuery 사용
  • TypeQuery 사용 가능
  • @NamedNativeQuery

네이티브 SQL 정리

  • 네이티브 SQL도 JPQL을 사용할 때와 마찬가지로 Query, TypeQuery(Named 네이티브 쿼리의 경우에만) 반환
  • JPQL API 사용 가능
  • 네이티브 SQL은 관리하기 쉽지 않고 자주 사용하면 특정 데이터베이스에 종속적인 쿼리가 증가해서 이식성 떨어짐
  • 될 수 있으면 표준 JPQL을 사용하고 기능이 부족하면 차선책으로 JPA 구현체가 제공하는 기능을 사용
  • 그래도 안되면 마지막 방법으로 네이티브 SQL 사용

스토어드 프로시저

  • proc_multiply: 입력 값을 두 배로 증가
  • @NamedStoredProcedureQuery

6. 객체지향 쿼리 심화

벌크 연산

  • 벌크 연산: 여러 건을 한 번에 수정하거나 삭제
  • executeUpdate(): 벌크 연산으로 영향을 받은 엔티티 건수 반환
  • 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리
  • 영속성 컨텍스트에 있는 엔티티의 내용과 데이터베이스에 있는 내용이 다를 수 있음
    ➡️ 해결 방법
    • em.refresh()
    • 벌크 연산 먼저 실행
    • 벌크 연산 수행 후 영속성 컨텍스트 초기화

영속성 컨텍스트와 JPQL

  • 조회한 엔티티만 영속성 컨텍스트가 관리
  • JPQL로 조회한 엔티티는 영속 상태
  • 영속성 컨텍스트에 이미 존재하는 엔티티가 있으면 기존 엔티티 반환
  • 영속성 컨텍스트는 영속 상태인 엔티티의 동일성 보장
  • em.find()는 영속성 컨텍스트에서 엔티티를 먼저 찾고 없으면 데이터베이스 조회
  • JPQL은 항상 데이터베이스에 SQL을 실행해서 결과 조회

JPQL과 플러시 모드

  • JPQL은 영속성 컨텍스트에 있는 데이터 고려하지 않고 데이터베이스에서 데이터 조회하므로 JPQL 실행 전에 영속성 컨텍스트의 내용을 데이터베이스에 반영해야 함
  • 쿼리에 설정하는 플러시 모드는 엔티티 매니저에 설정하는 플러시 몯보다 우선권 가짐
  • JPA 쿼리를 사용할 때 영속성 컨텍스트에는 있지만 아직 데이터베이스에 반영하지 않은 데이터 조회 불가 ➡️ 데이터 무결성에 심각한 피해
  • 플러시가 너무 자주 일어나는 상황에 FlushModeType.COMMIT 모드 사용하면 쿼리시 밠생하는 플러시 횟수를 줄여서 성능 최적화
profile
Backend Developer👩🏻‍💻

0개의 댓글