JPA/queryDsl

Select 문

lovineff 2020. 6. 9. 11:02

기본 Select문

"user" Entity에 매핑된 테이블의 모든 컬럼값을 조회하므로, 사용을 추천하지 않는다.

jpaQueryFactory
        .selectFrom(user)
        .fetch();

 

원하는 컬럼만 조회

com.test.react.Model.User.class 클래스에 데이터를 매핑하여 리턴한다.

".as()" 함수로 반환 클래스 매핑명을 설정한다.

jpaQueryFactory
        .select(Projections.fields(
            com.test.react.Model.User.class,
            user.id.as("userId"),
            user.name.as("name")
        )).from(user)
        .fetch();

 

JOIN 사용

jpaQueryFactory
        .select(Projections.fields(
            com.test.react.Model.User.class,
            user.id.as("userId"),
            user.name.as("name"),
            userDetail.id.as("userDetailId"),
            userDetail.age.as("age"),
            userDetail.address.as("address")
        )).from(user)
        .leftJoin(userDetail)
            .on(userDetail.userId.eq(user.id))
        .fetch();

 

SUB 쿼리 사용

Sub 쿼리는 JPAExpressions를 사용한다.

jpaQueryFactory
        .select(Projections.fields(
                UserDetailCnt.class,
                user.id.as("id"),
                user.name.as("name"),
                ExpressionUtils.as(
                    JPAExpressions
                        .select(userDetail.count())
                        .from(userDetail)
                        .where(userDetail.userId.eq(user.id))
                    , "detailCnt"
                )
        ))
        .from(user)
        .where(JPAExpressions
                .select(userDetail.count())
                .from(userDetail)
                .where(userDetail.userId.eq(user.id))
                .groupBy(userDetail.userId)
                .gt(0L)
        )
        .fetch();

실행 결과

select
    user0_.user_id as col_0_0_,
    user0_.name as col_1_0_,
    (select
            count(userdetail1_.id)
        from
            user_detail userdetail1_
        where
            userdetail1_.user_id=user0_.user_id
    ) as col_2_0_
from
    user user0_
where
(
    select
        count(userdetail2_.id)
    from
        user_detail userdetail2_
    where
        userdetail2_.user_id=user0_.user_id
    group by
        userdetail2_.user_id
)>0

 

 

From절 SUB 쿼리 사용

JPA JPQL 서브쿼리 한계점으로 from 절의 서브쿼리(인라인 뷰)는 지원하지 않는다. 

따라서 Querydsl에서도 인라인 뷰를 지원하지 않는다. 

해결 방법으로는 서브쿼리를 조인으로 변경 또는 Native SQL을 사용해야 한다.

 

 

Paging 처리(queryDsl 제공 함수 사용)

jpaQueryFactory
        .select(Projections.fields(
                com.test.react.Model.User.class,
                user.id.as("userId"),
                user.name.as("name"),
                userDetail.id.as("userDetailId"),
                userDetail.age.as("age"),
                userDetail.address.as("address")
        )).from(user)
        .leftJoin(userDetail)
            .on(userDetail.userId.eq(user.id))
        .offset((page <= 0) ? 0 : (page -1)) // page 처리는 0부터 시작되므로, -1 처리를 해야한다.
        .limit(blockCnt)
        .fetch();

 

내부 함수 호출

jpaQueryFactory
    .select(Projections.fields(OrdersNewDto.class,
                orders.id.as("id")
                , orders.name.as("name")
                , Expressions.stringTemplate("function('to_char', {0}, '{1s}')", orders.orderDate, ConstantImpl.create("YYYY.MM.DD")).as("newDate")
                , Expressions.stringTemplate("YEAR({0})||MONTH({0})||DAY({0})", orders.orderDate).as("newDate")
            ))
    .from(orders)
    .fetch();

 

 

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

DB 함수 호출  (0) 2021.03.22
queryDsl 모듈별 빌드  (0) 2021.03.09
Filter 이름별 조건 설정 방법  (0) 2021.03.09
동적 쿼리 생성  (0) 2020.06.09
UPDATE, DELETE 문  (0) 2020.06.09