오봉이와 함께하는 개발 블로그

JPA - 다형성 쿼리, 엔티티 직접 사용, Named 쿼리 본문

BE/JPA

JPA - 다형성 쿼리, 엔티티 직접 사용, Named 쿼리

오봉봉이 2022. 7. 6. 02:32
728x90

다형성 쿼리

위와 같이 설계되었을 때 특수한 기능들을 제공한다.

TYPE

  • 조회 대상을 특정 자식으로 한정할 수 있다
  • 예 : Item 중에 Book, Movie를 조회하라.
  • JPQL
    • SELECT i FROM Item i WHERE TYPE(i) IN (Book, Movie)
  • SQL
    • select i from i where i.DTYPE in ('B', 'M')

TREAT(JPA 2.1)

  • 자바의 타입 캐스팅과 유사하다.
  • 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용할 수 있다.
  • FROM, WHERE, SELECT에서 사용
  • JPQL
    • SELECT i FROM Item i WHERE TREAT(i as Book).author = 'kim'
  • SQL
    • SELECT i.* FROM Item i WHERE i.DTYPE = 'B' and i.author = 'kim'



엔티티 직접 사용

  • JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본키 값을 사용한다.

엔티티 직접 사용 - 기본키값

  • JPQL
    • select count(m.id) from Member m
      • 엔티티의 아이디를 사용
    • select count(m) from Member m
      • 엔티티를 직접 사용
  • SQL (JPQL 둘다 같은 다음 SQL 실행)
    • select count(m.id) as cnt from Member m
  • 엔티티를 파라미터로 전달
    • String jpql = "select m from Member m where m = :member";
    • .setParameter("member", member)
  • 식별자를 직접 전달
    • String jpql = "select m from Member m where m.id = :memberId";
    • .setParameter("memberId", memberId)
  • 실행된 SQL
    • select m.* from Member m where m.id=?

엔티티 직접 사용 - 외래키값

Team team = em.find(Team.class, 1L);
String qlString = "select m from Member m where m.team = :team";
List resultList = em.createQuery(qlString)
    .setParameter("team", team)
    .getResultList();
String qlString = "select m from Member m where m.team.id = :teamId";
List resultList = em.createQuery(qlString)
    .setParameter("teamId", teamId)
    .getResultList();
  • 실행된 SQL

select m.* from Member m where m.team_id=?




Named 쿼리

  • 미리 정의해서 이름을 부여해두고 사용하는 JPQL이다
  • 정적 쿼리이다.
  • 어노테이션, XML에 정의
  • 애플리케이션 로딩 시점에 초기화 후 재사용
  • 애플리케이션 로딩 시점에 쿼리를 검증한다.
    • 로딩 시점에 쿼리를 검증하기 때문에 실행 전에 오류를 방지할 수 있다.

어노테이션에 정의

@Entity
@NamedQuery(
name = "Member.findByUsername",
query="select m from Member m where m.username = :username")
public class Member {
}

List<Member> resultList = em.createNamedQuery("Member.findByUsername", Member.class)
                .setParameter("username", "회원1")
                .getResultList();

XML에 정의

[META-INF/persistence.xml]

<persistence-unit name="jpabook" >
<mapping-file>META-INF/ormMember.xml</mapping-file>
[META-INF/ormMember.xml]

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" version="2.1">
  <named-query name="Member.findByUsername">
  <query><![CDATA[
      select m
      from Member m
      where m.username = :username
      ]]></query>
  </named-query>

  <named-query name="Member.count">
  <query>select count(m) from Member m</query>
  </named-query>
</entity-mappings>

Named 쿼리 환경에 따른 설정

  • XML이 항상 우선권을 가진다.
  • 애플리케이션 운영 환경에 따라 다른 XML을 배포할 수 있다.
    • 솔루션을 개발했을 때 특정 상황마다 쿼리가 달라져야 할 때 매핑 파일을 따로 배포하면 된다.

번외

실무에서 Named 쿼리를 사용하는 것은 조금 보기 불편한 코드가 나올 수 있기 때문에, Spring Data JPA에서 제공하는 @Query를 통해서 Named 쿼리를 편하게 구현하도록 하자.

출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90

'BE > JPA' 카테고리의 다른 글

JPA 활용 1 - 도메인 모델과 엔티티 설계  (0) 2022.09.02
JPA - 벌크 연산  (0) 2022.07.06
JPA - 페치 조인 한계  (0) 2022.07.05
JPA - 페치 조인 기본  (0) 2022.07.04
JPA - 경로 표현식  (0) 2022.07.01
Comments