본문 바로가기
Backend/JPA

[JPQL] 프로젝션

by 2245 2023. 12. 24.

출처

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 - 인프런

현업에서 실제로 JPA로 개발을 하고 있습니다. 그런 입장에서보면 지금 작성하고 있는 코드들이 어떻게 작동하는지 이해하는데 큰 도움을 주는 강의입니다. 다음은 제가 느낀 이 강의의 장점들

www.inflearn.com

 

목차

     

     

    프로젝션?

    SELECT 절에 조회할 대상을 지정하는 것입니다. 

     

    • 프로젝션 대상: 엔티티, 임베디드 타입, 스칼라 타입 (숫자, 문자 등 기본 데이터 타입)
    • 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 → 스칼라 타입 프로젝션
    • 참고로, SELECT 다음 DISTINCT 넣으면 중복을 제거할 수 있습니다. 

     

    엔티티 프로젝션

    [예제] 영속화한 Member 객체를 em.clear()를 통해 컨텍스트를 비운 후, JPQL를 통해 가져오면, 해당 객체가 영속성 컨텍스트에서 관리가 될까? 

    Member member = new Member();
    member.setUsername("member1");
    member.setAge(10);
    em.persist(member);
    
    em.flush();
    em.clear();
    
    List<Member> result = em.createQuery("select m from Member m", Member.class)
                             .getResultList();
    
    Member.findMember = result.get(0); 
    findMember.setAge(20);  //영속성 컨텍스트에서 관리가 된다면, Update query가 발생한다. O
    
    tx.commit();
    Hibernate:
      update Member
      set
        age=?,
        TEAM_ID=?,
        username=?
      where
        id=?

     

    결론

    em.createQuery()를 통해 조회한 여러 개의 엔티티들 모두 영속성 컨텍스트에서 관리가 됩니다.

    ⇒ 프로젝션은 모두 영속성 컨텍스트에서 관리가 됩니다.

     

     

     

    여러 필드 조회

    SELECT m.username, m.age FROM Member m

     

    1. Query 타입으로 조회

    List resultList = em.createQuery("select m.username, m.age from Member m")
                        	.getResultList();
    
    Object o = resultList.get(0);
    Object[] result = (Obejct[]) o;
    System.out.println("username = " + result[0]);  //member1
    System.out.println("age = " + result[1]);     //10

     

    2. Object[] 타입으로 조회

    List<Object[]> resultList = em.createQuery("select m.username, m.age from Member m")
                                    .getResultList();
    
    Object[] result = resultList.get(0);
    System.out.println("username = " + result[0]);  //member1
    System.out.println("age = " + result[1]);     //10

     

    3. new 명령어로 조회

    DTO로 바로 조회

    package jpql;
    
    public class MemberDTO {
        private String username;
        private int age;
    
        public MemberDTO(String username, int age) {
            this.username = username;
            this.age = age;
        }
    
        //Getter, Setter ...
    }
    List<MemberDto> resultList = em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class)
                                    .getResultList();
    
    MemberDTO memberDTO = result.get(0);
    System.out.println("username = " + memberDTO.getUsername());  //member1
    System.out.println("age = " + memberDTO.getAge());     //10
    • 패키지 명을 포함한 전체 클래스명을 입력해야 합니다. 
    • 순서와 타입이 일치하는 생성자가 필요합니다. 

     

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

    [JPQL] 벌크 연산  (0) 2023.12.24
    [JPQL] 조인  (0) 2023.12.24
    [JPQL] 객체 지향 쿼리 기본 문법과 기능  (0) 2023.12.24
    [JPA] JPA의 다양한 쿼리 방법 소개  (0) 2023.12.24
    [JPA] 값 타입  (0) 2023.12.20