[인프런 김영한] JPA - JPQL 프로젝션(SELECT)

2021. 2. 16. 13:09프로그래밍 언어/Spring Framework

[인프런 김영한] JPA - JPQL 프로젝션(SELECT)


해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.

김영한 인프런 : www.inflearn.com/users/@yh

 

인프런 - 김영한의 강의들을 만나보세요.

우아한형제들 개발 팀장 (전: 카카오, SK플래닛) 저서: 자바 ORM 표준 JPA 프로그래밍

www.inflearn.com


▣ 프로젝션(SELECT)

SELECT m FROM Member m -> Entity 프로젝션
SELECT m.team FROM Member m -> Entity 프로젝션 , Team을 조인한다.
SELECT m.adress FROM Member m -> 임베디드 타입 프로젝션
SELECT m.username, m.age FROM Member m -> 스칼라 타입 프로젝션
DISTINCT로 중복제거 가능

 

 

◈ 프로젝션(SELECT) - 프로젝션으로 가지고온 Entity는 영속성 컨텍스트에 관리가 될까?

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);

// 영속성 컨텍스트에 관리가 되기 때문에 변경에 대해 update 쿼리문이 나감감
findMember.setAge(20);


// 실행
Hibernate: 
    /* insert com.jpa.Member
        */ insert 
        into
            Member
            (age, TEAM_ID, username, id) 
        values
            (?, ?, ?, ?)
Hibernate: 
    /* select
        m 
    from
        Member m */ select
            member0_.id as id1_0_,
            member0_.age as age2_0_,
            member0_.TEAM_ID as team_id4_0_,
            member0_.username as username3_0_ 
        from
            Member member0_
Hibernate: 
    /* update
        com.jpa.Member */ update
            Member 
        set
            age=?,
            TEAM_ID=?,
            username=? 
        where
            id=?

 

 

 

▣ 임베디드 타입 프로젝션

// 임베디드 타입 프로텍션
Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);

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

// Order에 있는 Address 컬럼 출력
em.createQuery("select o.address from Order o", Address.class).getResultList();


// 실행
select
	order0_.city as col_0_0_,
 	order0_.street as col_0_1_,
	order0_.zipcode as col_0_2_ 
from
	ORDERS order0_

 

 

 

▣ 스칼라 타입 프로젝션

// 스칼라 타입 프로젝션
Member member = new Member();
member.setUsername("member1");
member.setAge(10);
em.persist(member);

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

// 타입이 2개인데 어떻게 받을 수 있을까?
//        em.createQuery("select distinct m.username, m.age from Member m").getResultList();

// 1. Query 타입 조회
Query query = em.createQuery("select distinct m.username, m.age from Member m");

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

// 3. new 명령어로 조회
List<MemberDTO> resultNew = em.createQuery("select new com.jpa.MemberDTO(m.username, m.age) from Member m", MemberDTO.class).getResultList();
MemberDTO memberDTO = resultNew.get(0);
System.out.println("memberDTO.username = " + memberDTO.getUsername());
System.out.println("memberDTO.age = " + memberDTO.getAge());