JPA 기본 | JPQL 문법(2) - 프로젝션(SELECT)

2024. 7. 16. 21:36· 인프런 김영한 강의 정리/자바 ORM 표준 JPA 프로그래밍 기본편
목차
  1. 1. 프로젝션이란?
  2. 2. 프로젝션 대상
  3. 3. 프로젝션 대상 이해하기
  4. 4. 여러가지 타입을 조회하는 방법
  5. 4-1) Object[] 타입으로 조회
  6. 4-2) new 명령어로 조회
728x90

1. 프로젝션이란?

- SELECT 절에 조회할 대상을 지정하는 것

 

2. 프로젝션 대상

✔️엔티티, 임베디드 타입, 스칼라 타입(기본 데이터 타입)

 

관계형 데이터베이스는 테이블 내의 개별적인 값을 가지는 데이터들을 조회한다.

예를 들어, Employees 테이블에 EmployeeID, Name, Age와 같은 속성에 있는 값을 조회하는 거다.

프로젝션 대상이 스칼라 타입이라고 볼 수 있다.

 

JPQL에서는 관계형 데이터베이스와 달리 조회 대상이 더 넓다.

 

3. 프로젝션 대상 이해하기

✅ Member 엔티티 

@Entity
@Getter
@Setter
public class Member {

    @Id @GeneratedValue
    private Long id;
    private String username;
    private int age;

    @Embedded
    private Address address;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
}

Member 엔티티의 조회 대상들을 타입 별로 구분해보면, 

- 엔티티 타입: team

- 임베디드 타입 : address

- 스칼라 타입 : id, username, age

 

✅JPQL 조회 예시

SELECT m FROM Member m -- 엔티티 프로젝션
SELECT m.team FROM Member m -- 엔티티 프로젝션
SELECT m.address FROM Member m -- 임베디드 프로젝션
SELECT m.username, m.age FROM Member m -- 스칼라 타입 프로젝션

 

 

✅실행 메서드

public static void main(String[] args) {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try{
            //멤버 엔티티 저장
            Member member = new Member();
            member.setUsername("memberA");
            member.setAge(10);
            em.persist(member);

            em.flush();
            em.clear();

            //Member 조회
            List<Member> result = em.createQuery("select m from Member m", Member.class)
                    .getResultList();

            Member findMember = result.get(0);
            findMember.setAge(20); //update 쿼리실행
            
            //Team 조회
            List<Team> result2 = em.createQuery("select t from Member m join m.team t", Team.class)
                    .getResultList();
                    
            //Address 조회
            List<Address> result3 = em.createQuery("select m.address from Member m", Address.class)
                    .getResultList();
                    
            //여러 타입 조회 - Query 객체로 쿼리 실행하고 결과를 Object[]로 받기
            Query query = em.createQuery("select m.username, m.age from Member m");
            List<Object[]> result4 = query.getResultList();

            Object[] selectResult4 = result4.get(0);
            System.out.println("username = " + selectResult4[0]);
            System.out.println("age = " + selectResult4[1]);

            //여러 타입 조회 - new 명령어로 조회(new뒤에 패키지명)
            List<MemberDTO> result5 = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
                    .getResultList();

            MemberDTO memberDTO = result5.get(0);
            System.out.println("username = " + memberDTO.getUsername());
            System.out.println("age = " + memberDTO.getAge());
            

            tx.commit();
        }catch (Exception e){
            tx.rollback();
            e.printStackTrace(); //예외 출력
        }finally {
            em.close();
        }
    }

- Member를 조회하기 전에 em.clear()로 영속성 컨텍스트를 초기화 해주지만 Member 엔티티를 조회하며 영속성 컨텍스트에 다시 로드한다. 그래서 setAge()를 호출했을 때 update 쿼리가 실행되는 것이다.

 

- select m.team from Member m 로 작성하면 team을 조회할 때 조인쿼리가 실행된다.

select t from Member m join Team t 처럼 join이 발생한다는 것을 코드만 봐도 이해할 수 있도록 명시해주는 게 좋다.

 

- Address와 같은 임베디드 타입은 임베디드 타입이 속해있는 엔티티를 거쳐서 조회할 수 있다. 

select a from Address a 이런 쿼리로 조회할 수 없다는 말이다.

 

4. 여러가지 타입을 조회하는 방법

- username은 String 타입이고 age는 int 타입이기때문에 반환되는 타입이 명확하지 않다.

여러가지 타입을 한번에 조회하는 두가지 방법이 있다.

 

4-1) Object[] 타입으로 조회

Query 객체로 JPQL 쿼리를 실행하고 결과를 Object[] 타입으로 받아서 조회하는 방법.

(메서드 체이닝으로 처음부터 Object[] 타입으로 받을 수 있으나 Query 복습겸 넣음)

쿼리에서 조회 대상의 순서를 어떻게 작성했는지 알아야하기 때문에 코드가 깔끔하지 않다.

 

4-2) new 명령어로 조회

먼저 DTO 클래스가 필요하다.

@Getter
@Setter
public class MemberDTO {
    private String username;
    private int age;

    public MemberDTO(String username, int age) {
        this.username = username;
        this.age = age;
    }
}
  • new 문법은 결과를 엔티티가 아닌 특정 DTO로 매핑하기 위해 사용된다.
  • JPQL 쿼리를 실행하면 생성자를 호출해서 MemberDTO 인스턴스가 생성된다.
  • DTO에 생성자를 필수로 만들어줘야한다.
  • Object[]타입과 달리, new 명령어로 조회를 하면 getter를 사용할 수 있기 때문에 코드가 좀 더 명확해진다.

 

 

 

728x90

'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글

JPA 기본 | JPQL 문법(4) - ENUM 타입,상속관계 엔티티 표현  (0) 2024.07.17
JPA 기본 | JPQL 문법(3) - 페이징, 조인, 서브쿼리  (0) 2024.07.17
JPA 기본 | JPQL 기본 문법(1) 쿼리 API, 파라미터 바인딩  (0) 2024.07.15
JPA 기본 | 객체지향 쿼리 언어 알아보기(JPQL, QueryDSL 등)  (0) 2024.07.15
JPA 기본 | 데이터 타입(3) - 값 타입 컬렉션  (0) 2024.07.14
  1. 1. 프로젝션이란?
  2. 2. 프로젝션 대상
  3. 3. 프로젝션 대상 이해하기
  4. 4. 여러가지 타입을 조회하는 방법
  5. 4-1) Object[] 타입으로 조회
  6. 4-2) new 명령어로 조회
'인프런 김영한 강의 정리/자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
  • JPA 기본 | JPQL 문법(4) - ENUM 타입,상속관계 엔티티 표현
  • JPA 기본 | JPQL 문법(3) - 페이징, 조인, 서브쿼리
  • JPA 기본 | JPQL 기본 문법(1) 쿼리 API, 파라미터 바인딩
  • JPA 기본 | 객체지향 쿼리 언어 알아보기(JPQL, QueryDSL 등)
백엔드 개발자 - 젤리곰
백엔드 개발자 - 젤리곰
오늘도 배움이 있는 하루가 되길 바라는 개발자
백엔드 개발자 - 젤리곰
backend-gummyBear
백엔드 개발자 - 젤리곰
전체
오늘
어제
  • 분류 전체보기 (145)
    • 인프런 김영한 강의 정리 (60)
      • 스프링 핵심원리 기본편 (12)
      • 모든 개발자를 위한 HTTP 웹 기본 지식 (10)
      • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (3)
      • 자바 ORM 표준 JPA 프로그래밍 기본편 (28)
      • 실전! Querydsl (6)
    • Spring (2)
    • 프로젝트일지 (6)
    • 프로그래밍 언어 (20)
      • Java (17)
      • JavaScript (3)
      • Python (0)
    • 데이터베이스 (4)
      • Oracle (2)
      • ORM (1)
      • SQL 튜닝 (1)
    • 형상관리 (1)
      • Git (0)
    • 알고리즘&자료구조 (34)
      • Algorithm (31)
      • Data Structure (1)
    • CS지식 (4)
    • Cloud (5)
    • 일기 (8)
      • 공부 일기 (3)
      • 독서 일기 (2)
      • 마음 일기 (3)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 다운캐스팅
  • 데이터베이스정규화
  • jquery와javascript
  • 프론트엔드개발자업무
  • dfs알고리즘
  • 커스텀annotation
  • 인프콘
  • SublimeText단축키
  • 스프링컨텍스트
  • LeetCode200번
  • 객체지향의사실과오해
  • ORM프레임워크
  • LeetCode17번
  • #{}와${}의차이
  • 업캐스팅
  • 클라이언트서버통신
  • 객체지향방법론
  • 힙자료구조
  • 인터페이스
  • 프론트엔드역사

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
백엔드 개발자 - 젤리곰
JPA 기본 | JPQL 문법(2) - 프로젝션(SELECT)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.