JPQL 프로젝션 (SELECT)

JPQL 프로젝션, DTO 매핑, 그리고 간편한 페이징 API 사용법을 자세히 알아봅니다.

프로젝션

-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

-연관관계를 맺고 있는 JPQL 의 컨벤션

// 아래의 두 쿼리는 같은 결과를 지닌다.
// 하지만 조인되고 있따는 결과를 좀 더 명시적으로 나타내기 위해, 하단의 쿼리를 사용하는 것이 좋다.
em.createQuery("select m.team from Member m", Team.class);
em.createQuery("select t from Member m join m.team t");

-Entity 가 아닌 DTO 에 매핑

// MemberDTO 에 필요한 속성들을 봅은 다음에, 생성자를 통해서 뽑아낼 수 있다.
// 단, 생성자를 호출햘 때에는 패키지명을 모두 써줘야 한다.
em.createQuery("select new jpql.MemberDTO(m.username, m.age) from Member m", MemberDTO.class).getResultList();

 

 


 

* Pagination API

JPA에서는 페이징 처리를 매우 쉽게 할 수 있다. 기존의 오라클, MSSQL 에서 복잡하게 페이징 처리를 했던 것에 비하면, 매우 놀랍다..

// 조회 시작 위치 (0부터 시작)
.setFirstResult(int startPosition);
// 조회할 데이터 수 
.setMaxResults(int maxResult);

// 와...
em.createQuery("select m from Member m order by m.regdate desc", Member.class)
  .setFirstResult(0)
  .setMaxResults(10)
  .getResultList();

Oracle 기준으로 실행되는 쿼리를 보면

SELECT * FROM 
    (
        SELECT ROW_.*, ROWNUM ROWNUM_
        FROM (
            SELECT 
                M.ID AS ID 
                , M.AGE AS AGE
                , M.TEAM_ID AS TEAM_ID 
                , M.NAME AS NAME 
            FROM Member M 
            ORDER BY M.NAME
        ) ROW_
        WHERE ROWNUM <= ?
    )
WHER ROWNUM_ > ?

 


이것도 읽어보세요