Study/실전! QueryDSL

Day 1. QueryDSL 소개 및 프로젝트 설정

주지민 2021. 9. 19. 17:30
반응형

본 포스트는 인프런 - 실전! QueryDSL의 강의를 듣고 공부한 내용입니다

https://www.inflearn.com/course/Querydsl-%EC%8B%A4%EC%A0%84

 

실전! Querydsl - 인프런 | 강의

Querydsl의 기초부터 실무 활용까지 한번에 해결, 본 강의는 자바 백엔드 개발의 실전 코스를 완성하는 마지막 강의 입니다. 스프링 부트와 JPA 실무 완전 정복 로드맵을 우선 확인해주세요. 로드

www.inflearn.com


1. QueryDSL 소개

  • 최근 프로젝트들은 SpringBoot + Spring Data JPA 조합으로 많이 활용하는 추세
  • 하지만 비즈니스 로직에 따라 복잡한 쿼리, 검색 조건에 따라 동적 쿼리들을 작성할 일이 생겼고, 이를 좀 더 편리하게 해결해주고자 하는 기술로 QueryDSL을 사용
  • QueryDSL이란?
    • 쿼리를 자바 코드로 작성하여 문법 오류를 컴파일 시점에서 잡아준다
    • 동적 쿼리 문제도 해결
    • 쉬운 SQL 스타일 문법
  • 필요성
    • 쿼리를 문자로 다루는 것은 너무 어렵다 ( 실수가 날 확률이 높다 ) 또한 실수를 런타임 시점에서 잡을 수 있다
    • QueryDSL을 사용하면 자바 코드로 작성하기 때문에 문자로 다뤘을 때 생기는 문제점들을 방지할 수 있다
    • 실수를 자바 컴파일 시점에서 잡을 수 있다
    • IDE의 도움 또한 받을 수 있다 ( 코드 자동 완성 )
    • 코드의 재활용 또한 가능

 

2. 프로젝트 설정

  • 의존성 설정 ( Gradle )
    • SpringBoot Web
    • Spring Data JPA
    • MySQL Driver
    • H2 Database
    • Lombok
    • QueryDSL
  • Gradle Code
    // build.gradle
    plugins {
        id 'org.springframework.boot' version '2.5.4'
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
        id 'java'
    }
    
    group = 'study'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '11'
    
    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation 'com.querydsl:querydsl-jpa'
        compileOnly 'org.projectlombok:lombok'
        runtimeOnly 'com.h2database:h2'
        runtimeOnly 'mysql:mysql-connector-java'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    test {
        useJUnitPlatform()
    }
    
    def querydslDir = "$buildDir/generated/querydsl"
    
    querydsl {
        jpa = true
        querydslSourcesDir = querydslDir
    }
    sourceSets {
        main.java.srcDir querydslDir
    }
    configurations {
        querydsl.extendsFrom compileClasspath
    }
    compileQuerydsl {
        options.annotationProcessorPath = configurations.querydsl
    }​
    • def querydslDir = "$buildDir/generated/querydsl"
      • 프로덕션 코드들이 있는 패키지안의 @Entity들을 보고 'Q' + {Class Name}으로 클래스를 뽑아내는 위치
    • gradlew compileQuerydsl
      • 해당 명령어로 빌드하면 위에서 설정한 Q타입 클래스들이 생성된다 ( 설정한 plugin과 맞물려서 )
      • QueryDSL은 이렇게 생성된 Q타입 클래스를 이용해 쿼리를 만들어낸다
    • 유의사항
      • Q타입들은 프로젝트에서 생성되어 관리되는 클래스이기 때문에 절대 Git에 공유되면 안된다
      • 위의 방법대로 Build 폴더 안에 넣으면 자동으로 ignore 처리되고 clean시 날라가기 때문에 좋은 것 같다
  • DataSource 설정
    • local로는 embedded h2를 사용하고, 실제 dev 환경에서는 MySQL을 통해 실습하려고 셋팅했습니다
    • H2 Database ( local profile )
      // application-local.yml
      spring:
        config:
          activate:
            on-profile: local
      
        h2:
          console:
            enabled: true
      
        datasource:
          driver-class-name: org.h2.Driver
          url: jdbc:h2:mem:localdb;DB_CLOSE_DELAY=-1
          username: sa
      
        jpa:
          hibernate:
            ddl-auto: create
          properties:
            hibenate:
              format_sql: true
      
      logging:
        level:
          org.hibernate.SQL: debug
    • MySQL ( dev profile )
      // application-dev.yml
      spring:
        config:
          activate:
            on-profile: dev
      
        output:
          ansi:
            enabled: always
      
        datasource:
          hikari:
            driver-class-name: com.mysql.cj.jdbc.Driver
            jdbc-url: jdbc:mysql://localhost:3306/my-querydsl?serverTimezone=UTC&characterEncoding=UTF-8
            username: root
            password: 1234
      
        # JPA
        jpa:
          hibernate:
            ddl-auto: create
          properties:
            hibernate:
              format_sql: true
              dialect: org.hibernate.dialect.MySQL57Dialect
          show-sql: true
      
      logging:
        level:
          org.hibernate.SQL: debug​


      CREATE SCHEMA `my-querydsl` DEFAULT CHARACTER SET utf8;​

 

3. 알아두면 좋을 지식

  • @SpringBootTest의 @Transactional이 걸리게되면 기본적으로 롤백 정책을 가져간다
    • 롤백하고 싶지 않다면, @Commit 혹은 @Rollback(false)을 추가해주도록 하자
  • spring.jpa.properties.hibernate의 format_sql과 show_sql 설정은 sout으로 찍히는 설정이다
  • logging.level.org.hibernate.SQL으로 하는 설정은 로깅(slf4) 설정이다
  • 따라서 둘다 설정하면.. 쿼리가 두번 찍히므로 로깅 설정을 했다면 show_sql 설정은 꺼두자
  • 쿼리의 바인딩 되는 파라미터를 보고 싶을때
    • 첫번째 방법: logging.level.org.hibernate.type 설정을 trace로 설정
    • 두번째 방법: p6spy-spring-boot-stater 의존성 추가  ( 반드시 성능을 확인한 후에 운영에 적용 )
      
      // build.gradle
      
      // https://mvnrepository.com/artifact/com.github.gavlyukovskiy/p6spy-spring-boot-starter
      implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.7.1'

 

728x90
반응형