본문 바로가기
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