Java/Spring

QueryDSL 사용하기

체리필터 2019. 8. 8. 16:18
728x90
반응형

JPA를 사용하면서 QueryDSL을 셋팅하고 사용하는 부분에 있어서 매번 헷깔려 정리한다.

 

QueryDSL을 사용하기 위해서 build.gradle 파일에 아래의 내용을 추가 해 준다.

plugins {
	...
    
    id 'idea'
    id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
    
    ...
}

dependencies {
	...
    
    implementation 'com.querydsl:querydsl-apt:4.1.4'
    implementation 'com.querydsl:querydsl-jpa:4.1.4'
    
    ...
}

ext {
    querydslSrcDir = 'src/main/generated'
    queryDslVersion = '4.1.4'
}

configurations {
    querydsl.extendsFrom compileClasspath
}

querydsl {
    library = "com.querydsl:querydsl-apt"
    querydslSourcesDir = 'src/main/generated'
    jpa = true
    querydslDefault = true
}

sourceSets {
    main {
        java {
            srcDirs += file(querydslSrcDir)
        }
    }
}

idea {
    module {
        generatedSourceDirs += file(querydslSrcDir)
    }
}

 

Entity 작성

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@EntityListeners(value = { AuditingEntityListener.class })
@Table(name = "user")
@Getter
@Setter
public class YeogiUser {
    @Id
    @Column(name="uno")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;
    
    ....
    
    @UpdateTimestamp
    @Column(name = "uedit")
    private LocalDateTime updatedAt;

    @CreationTimestamp
    @Column(name="ureg", updatable = false)
    private LocalDateTime createdAt;
    
    ....
    
    @QueryProjection
    public YeogiUser(long userId, LocalDateTime updatedAt, LocalDateTime createdAt) {
        this.userId = userId;
        this.updatedAt = updatedAt;
        this.createdAt = createdAt;
    }
}

 

기본 JPA Interface 작성

public interface YeogiUserQueryRepository extends JpaRepository<YeogiUser, Long>, YeogiUserQueryRepositoryCustom {
    ...
}

 

Custom으로 QueryDSL을 사용할 interface 작성

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface YeogiUserQueryRepositoryCustom {
    Page<YeogiUser> findByUserParamForIpcc(Pageable pageable, UserParamForIpcc userParamForIpcc);
}

 

Custom interface 구현 클래스 작성

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ConstructorExpression;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import kr.co.within.cms.user.api.application.params.UserParamForIpcc;
import kr.co.within.cms.user.api.domain.yeogi.user.entity.QYeogiUser;
import kr.co.within.cms.user.api.domain.yeogi.user.entity.YeogiUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;

public class YeogiUserQueryRepositoryImpl extends QuerydslRepositorySupport implements YeogiUserQueryRepositoryCustom {
    public YeogiUserQueryRepositoryImpl() {
        super(YeogiUser.class);
    }

    @Override
    public Page<YeogiUser> findByUserParamForIpcc(Pageable pageable, UserParamForIpcc userParamForIpcc) {
        JPAQueryFactory query = new JPAQueryFactory(this.getEntityManager());
        QYeogiUser yegiUser = QYeogiUser.yeogiUser;

        JPAQuery<YeogiUser> jpaQuery = query
                .select(getYeogiUserProjection())
                .from(yegiUser);

        if (CollectionUtils.isEmpty(userParamForIpcc.getUserIdList()) == false) {
            jpaQuery = jpaQuery.where(yegiUser.userId.in(userParamForIpcc.getUserIdList()));
        }

        if (StringUtils.isNotEmpty(userParamForIpcc.getLoginId())) {
            jpaQuery = jpaQuery.where(yegiUser.loginId.eq(userParamForIpcc.getLoginId()));
        }

        if (StringUtils.isNotEmpty(userParamForIpcc.getNickname())) {
            jpaQuery = jpaQuery.where(yegiUser.nickname.eq(userParamForIpcc.getNickname()));
        }

        if (StringUtils.isNotEmpty(userParamForIpcc.getPhone())) {
            jpaQuery = jpaQuery.where(yegiUser.phone.eq(userParamForIpcc.getPhone()));
        }

        QueryResults<YeogiUser> list = jpaQuery
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .orderBy(new OrderSpecifier(Order.ASC, yegiUser.userId))
                .fetchResults();

        return new PageImpl<>(list.getResults(), pageable, list.getTotal());
    }

    private ConstructorExpression<YeogiUser> getYeogiUserProjection() {
        QYeogiUser yegiUser = QYeogiUser.yeogiUser;

        return Projections.constructor(YeogiUser.class,
                yegiUser.userId, yegiUser.userStatus, yegiUser.userType, yegiUser.ano, yegiUser.loginId, yegiUser.loginPassword,
                yegiUser.nickname, yegiUser.name, yegiUser.facebookId, yegiUser.updatedAt, yegiUser.createdAt,
                yegiUser.deviceId, yegiUser.myRecommendationCode, yegiUser.friendRecommendationCode, yegiUser.recommededCount,
                yegiUser.snsAgree, yegiUser.uaname, yegiUser.group, yegiUser.alarmStatus, yegiUser.latestLodging,
                yegiUser.alarmAgreeDate, yegiUser.phone, yegiUser.lastLoginAt);
    }
}

 

사용

    @Autowired
    private YeogiUserQueryRepository yeogiUserQueryRepository;

    public Page<YeogiUser> getUserList(Pageable pageable, UserParamForIpcc userParamForIpcc) {
        return yeogiUserQueryRepository.findByUserParamForIpcc(pageable, userParamForIpcc);
    }

 

자세한 설명은 생략한다.

 

728x90
반응형