web/JAVA & SpringBoot

가독성을 늘려주는 Query Dsl #1

3hoon 2023. 1. 12. 02:46

쿼리를 자바 코드로 작성할 수 있게 도와주는 기술로
JPA로는 어려운 복잡한 쿼리나 동적쿼리까지 해결할 수 있는 장점이 있다.
또한 문법의 오류를 컴파일시에 찾아 낼 수 있다는 장점을 가지고 있다.

1. Query Dsl 특징


1. 쿼리를 코드로 작성 가능 (ide의 자동완성 기능을 사용할 수 있다)
2. 컴파일시 문법 오류를 찾아낼 수 있음
3. 동적 쿼리 구현 가능
4. 가독성 향상 가능
* 동적쿼리(Dynamic SQL) : 특정 조건들이나 상황에 따라 변경되는 쿼리
* 정적쿼리(Static SQL) : 어떤 조건 또는 상황에도 변경되지 않는 쿼리

 

2. Query Dsl 적용


config 패키지

package com.example.pirate99_final.map.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
public class QuerydslConfiguration {
    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }
}

 

bulid.gradle

// query dsl 버전
buildscript {
    ext {
        queryDslVersion = "5.0.0"
    }
}

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

dependencies {
		implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
    implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
    annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}"
}

//querydsl 추가 시작
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
}

sourceSets {
    main.java.srcDir querydslDir
}

configurations {
    querydsl.extendsFrom compileClasspath
}

compileQuerydsl {
    options.annotationProcessorPath = configurations.querydsl
}

 

QEntity 구현


Gradle -> other -> compileQueryDsl을 실행하면

QEntity

package com.example.pirate99_final.map.entity;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;


/**
 * QNaver is a Querydsl query type for Naver
 */
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QNaver extends EntityPathBase<Naver> {

    private static final longserialVersionUID= 1431852996L;

    public static final QNavernaver= new QNaver("naver");

    public final StringPath address = createString("address");

    public final NumberPath<Long> id = createNumber("id", Long.class);

    public final NumberPath<Integer> postnumber = createNumber("postnumber", Integer.class);

    public final NumberPath<Integer> reviewcnt = createNumber("reviewcnt", Integer.class);

    public final StringPath roadnameaddress = createString("roadnameaddress");

    public final NumberPath<Double> starscore = createNumber("starscore", Double.class);

    public final StringPath storename = createString("storename");

    public final StringPath typeofbusiness = createString("typeofbusiness");

    public final NumberPath<Double> xcoordinate = createNumber("xcoordinate", Double.class);

    public final NumberPath<Double> ycoordinate = createNumber("ycoordinate", Double.class);

    public QNaver(String variable) {
        super(Naver.class,forVariable(variable));
    }

    public QNaver(Path<? extends Naver> path) {
        super(path.getType(), path.getMetadata());
    }

    public QNaver(PathMetadata metadata) {
        super(Naver.class, metadata);
    }

}

 

3. Query Dsl 구현


RepositoryCustom

package com.example.pirate99_final.map.repository;

import com.example.pirate99_final.map.entity.Naver;

import java.util.List;

public interface NaverRepositoryCustom {
    Naver findByStoreName(String storeName);                    

    List<Naver> findByStoreNameInclude(String storeName); 

    List<Naver> findByroadAddressInclude(String roadNameAddress); 

    List<Naver> findByBusiness(String typeOfBusiness);          

    List<Naver> OrderByStarScore();    

    List<Naver> OrderByStarScoreDESC(); 

    List<Naver> OrderByReview();

    List<Naver> OrderByReviewDESC(); 

    List<Naver> BetweenStarScoreHigh(); 

    List<Naver> BetweenStarScoreLow();    

    List<Naver> BetweenReviewHigh();    

    List<Naver> BetweenReviewLow(); 
}

 

RepositoryImpl

package com.example.pirate99_final.map.repository;

import com.example.pirate99_final.map.entity.Naver;
import com.example.pirate99_final.map.entity.QNaver;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.apache.commons.lang3.StringUtils;

import java.util.List;


@Repository
@RequiredArgsConstructor
public class NaverRepositoryImpl implements NaverRepositoryCustom {
    private final JPAQueryFactory queryFactory;

    public Naver findByStoreName(String storeName) {                        
        QNaver naver = QNaver.naver;                                        
        Naver findByStoreName = queryFactory
                .selectFrom(naver)
                .where(naver.storename.eq(storeName))                       
                .fetchOne();                                                
        return findByStoreName;
    }

    public List<Naver> findByStoreNameInclude(String storeName) {           
        QNaver naver = QNaver.naver;                                        
        List<Naver> StoreNameInclude = queryFactory
                .selectFrom(naver)
                .limit(10)                                                  
                .where(naver.storename.contains(storeName))                 
                .fetch();                                                   
        return StoreNameInclude;
    }

    public List<Naver> findByroadAddressInclude(String roadNameAddress) {   
        QNaver naver = QNaver.naver;
        List<Naver> roadAddressInclude = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.roadnameaddress.contains(roadNameAddress))     
                .fetch();
        return roadAddressInclude;
    }

    public List<Naver> findByBusiness(String typeOfBusiness) {              
        QNaver naver = QNaver.naver;
        List<Naver> businessType = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.typeofbusiness.eq(typeOfBusiness))             
                .fetch();
        return businessType;
    }

    public List<Naver> OrderByStarScore() {                                
        QNaver naver = QNaver.naver;
        List<Naver> starScoreASC = queryFactory
                .selectFrom(naver)
                .limit(10)
                .orderBy(naver.starscore.asc())                             
                .fetch();
        return starScoreASC;
    }

    public List<Naver> OrderByStarScoreDESC() {                             
        QNaver naver = QNaver.naver;
        List<Naver> starScoreDESC = queryFactory
                .selectFrom(naver)
                .limit(10)
                .orderBy(naver.starscore.desc())                            
                .fetch();
        return starScoreDESC;
    }

    public List<Naver> OrderByReview() {                                    
        QNaver naver = QNaver.naver;
        List<Naver> reviewASC = queryFactory
                .selectFrom(naver)
                .limit(10)
                .orderBy(naver.reviewcnt.asc())
                .fetch();
        return reviewASC;
    }

    public List<Naver> OrderByReviewDESC() {                               
        QNaver naver = QNaver.naver;
        List<Naver> reviewDESC = queryFactory
                .selectFrom(naver)
                .limit(10)
                .orderBy(naver.reviewcnt.desc())
                .fetch();
        return reviewDESC;
    }

    public List<Naver> BetweenStarScoreHigh() {                             
        QNaver naver = QNaver.naver;
        List<Naver> BetweenStarScoreHigh = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.starscore.between(4, 5))                       
                .orderBy(naver.starscore.desc())
                .fetch();
        return BetweenStarScoreHigh;
    }

    public List<Naver> BetweenStarScoreLow() {                              
        QNaver naver = QNaver.naver;
        List<Naver> BetweenStarScoreLow = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.starscore.between(0, 2))                       
                .orderBy(naver.starscore.desc())
                .fetch();
        return BetweenStarScoreLow;
    }

    public List<Naver> BetweenReviewHigh() {                                
        QNaver naver = QNaver.naver;
        List<Naver> BetweenReviewHigh = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.reviewcnt.between(1000, 1000000))              
                .orderBy(naver.reviewcnt.desc())
                .fetch();
        return BetweenReviewHigh;
    }

    public List<Naver> BetweenReviewLow() {                                 
        QNaver naver = QNaver.naver;
        List<Naver> BetweenReviewLow = queryFactory
                .selectFrom(naver)
                .limit(10)
                .where(naver.reviewcnt.between(0, 10))                     
                .orderBy(naver.reviewcnt.desc())
                .fetch();
        return BetweenReviewLow;
    }
}