본문 바로가기
스프링/JPA

[JPA] Spirng Data JPA에서 QueryDSL 사용하기

by 책 읽는 개발자_테드 2021. 7. 20.
반응형

QueryDSL에 대한 이해와 사용 방법 설명합니다. 모든 설명은 프로젝트에 Spirng Data JPA 의존성이 추가된 것으로 가정합니다.

 

학습 목표

- QueryDSL이란?

- 스프링부트에서 QuerySQL 사용하기

   - Gradle에 QuerySQL 설정 추가

   - QuerydslPredicateExecutor 인터페이스 

   - 테스트코드 작성


QueryDSL이란?

JPA에서 동적으로 쿼리를 처리하는 방법

 

QueryDSL을 사용하는 이유는 무엇일까?

웹 애플리케이션에서 검색 기능을 구현할 때 검색 조건은 다양하게 구성된다. 다양한 검색 쿼리를 미리 등록해서 사용하면 비슷한 쿼리가 너무 많아져 관리하기 어렵다. QueryDSL을 사용하면 동적으로 쿼리를 처리하므로 해당 문제를 해결할 수 있다.

 

스프링부트에서 QuerySQL 사용하기

Gradle에 QuerySQL 설정 추가

buildscript{

  ext{
     queryDslVersion = "4.4.0"
  }

...생략

dependencies {

  implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
  annotationProcessor(
        "javax.persistence:javax.persistence-api",
        "javax.annotation:javax.annotation-api",
        "com.querydsl:querydsl-apt:${queryDslVersion}:jpa")
}

sourceSets {

  main {
     java {
        srcDirs = ["$projectDir/src/main/java", "$projectDir/build/generated"]
     }
  }
}

위 설정을 추가하면 엔티티마다 Q-Type 클래스가 생성된다. 예를들어 User.class라는 엔티티가 있다면 QUser.class가 생성된다. 해당 클래스는 검색조건을 선택하는 역할을 한다.

QuerydslPredicateExecutor 인터페이스 

▶ Spring Data JPA가 제공하는 인터페이스로, 원하는 엔티티의 리포지토리에서 구현하면 QuerydslPredicateExecutor에서 제공하는 메소드를 이용하여 동적 쿼리를 작성할 수 있다.

 

설명을 위해 특정 상황을 가정해보자.

 

프로젝트에는 User라는 엔티티가 존재한다.

@Entity
@Getter
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotEmpty
    private String phone;

    @NotEmpty
    private String name;

    @NotEmpty
    private String sex;
}

해당 엔티티에 대한 데이터가 데이터베이스에 다음과 같이 저장되어있다.

해당 엔티티에 대하여 QuerydslPredicateExecutor 인터페이스를 상속하는 레포지토리를 생성한다. 

import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;


public interface UserRepository extends CrudRepository<User, Long>, QuerydslPredicateExecutor<User> {
}

이렇게하면 User 엔티티에 대한 동적 쿼리를 작성할 준비가 완료된다.

 

테스트코드 작성

동적 쿼리를 작성할 준비가 완료되었으니, 테스트를 진행하자. 프로젝트에서 UserTest 클래스를 생성하고 아래와 같이 작성한다.

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class UserTest {

    @Autowired
    UserRepository userRepository;

    @Test
    void testDynamicQuery(){
        String name = "박xx";
        String phone = "010-0000-0000";
        String sex = "남";

        BooleanBuilder builder = new BooleanBuilder();
        QUser qUser = QUser.user;

        if(name != null && name != "")
            builder.and(qUser.name.like("%" + name + "%"));
        if(phone != null && phone != "")
            builder.and(qUser.phone.like("%" + phone + "%"));
        if(sex != null && sex != "")
            builder.and(qUser.sex.eq(sex));

        Iterable<User> users = userRepository.findAll(builder);

        for(User user: users) {
            System.out.println("검색된 유저:"+user);

        }
    }

위 코드는 name, phone, sex 변수가 비어있지 않을 때만 해당 변수가 포함된 데이터를 모두 가져오는 코드다.

 

BooleanBuilder - 레포지토리 메소드에 검색 조건을 더하는 역할을 한다.

QUser - like(검색조건이 포함된), eq(검색 조건과 똑같은) 등 검색 조건을 선택하여 BooleanBuilder에 입력하는 역할을 한다.

 

 

코드 실행결과

 

출처

스프링부트퀵스타트

반응형

'스프링 > JPA' 카테고리의 다른 글

[JSP] 필터(Filter)란?  (0) 2021.10.05
[JPA] 오류 해결: “Data too long for column”  (0) 2021.05.29
[JPA] 오류해결: Field 'id' doesn't have a default value  (0) 2021.05.27
[JPA] JPA란?  (0) 2021.04.20

댓글