JPA의 쿼리 메서드와 @Query를 통해 많은 기능을 구현할 수는 있으나 선언할 때 고정된 형태의 값을 가진다는 단점이 있다. 이 때문에 단순한 몇 가지의 검색 조건을 만들어야 하는 상황에서는 기본 기능만으로 충분하지만, 복잡한 조합을 이용하는 경우의 수가 많은 상황에서는 동적으로 쿼리를 생성해서 처리할 수 있는 기능이 필요하다. 이럴때 Querydsl을 이용하면 복잡한 검색조건이나 조인,서브 쿼리 등의 기능도 구현이 가능하다.
SQL, JPQL의 문제점
- 문자열이며 Type-check가 불가능 하다.
- 잘 해봐야 어플리케이션 로딩 시점에 알 수 있고 컴파일 시점에 알 수 있는 방법이 없다.(자바와 문자열의 한계)
- 해당 로직 실행 전까지 작동여부 확인을 할 수 없다.
- 해당 쿼리 실행 시점에 오류를 발견한다.
QueryDSL
- SQL, JPQL을 코드로 작성할 수 있도록 도와주는 빌더 API, 오픈소스
- 문자가 아닌 코드로 작성
- 컴파일 시점에 문법 오류를 발견
- 코드 자동완성(IDE의 도움)
- 코드 모양의 JPQL과 거의 비슷하고 단순하고 쉽다.
- 정적 쿼리가 아닌 동적 쿼리이다.
Querydsl를 이용하면 코드 내부에서 상황에 맞는 쿼리를 생성할 수 있지만 이를 위해서는 작성된 엔티티 클래스를 그대로 이용하지 않고 'Q도메인'을 이용하여야 한다. 따라서 엔티티 클래스를 Q도메인 클래스로 변환하는 추가적인 설정이 필요하다.
Querydsl 설정
1.plugins 항목에 querydsl 관련 부분을 추가한다.
2.buildscript에 DslVersion을 추가한다.
3.dependencies 항목에 필요한 라이브러리를 추가한다.
4.Gradle에서 사용할 추가적인 task를 추가한다.
위 상태에서 compileQuerydsl를 실행하면 build 폴더 안에 'Q'로 시작하는 엔티티 클래스의 이름과 동일하게 만들어지는 파일을 볼수있다. 생성된 QGuestBook 클래스를 보면 내부적으로 선언된 필드(칼럼)들이 변수 처리 된 것을 확인할 수 있다.
자동으로 생성된다라는 의미는 즉, Q로 시작되는 클래스들은 개발자가 직접 건드리지 않는다는 의미이다. gradle의 compileQuerydsl과 같은 task를 통해서 자동으로 생성되는 방법만을 사용한다. Querydsl를 이용하게 되면 Repository인터페이스 역시 QuerydslPredicateExecutor 인터페이스를 추가로 상속한다.
5.QuerydslPredicateExecutor 인터페이스 추가 상속
Querydsl의 사용법
- BooleanBuilder를 생성한다.
- 조건에 맞는 구문은 Querydsl에서 사용하는 Pedicate 타입의 함수를 생성한다.
- BooleanBuilder에 작성된 Predicate를 추가하고 실행한다.
Querydsl를 사용하여 제목에 '1'이라는 글자가 있는 엔티티를 검색(단일 항목 검색 테스트)
QGuestbook qGuestbook = QGuestbook.guestbook;
가장 먼저 동적으로 처리하기 위해 Q도메인 클래스를 얻어온다. Q도메인 클래스를 이용하려면 엔티티 클래스에 선언된 title, content같은 필드들을 변수로 활용할 수 있다.
BooleanBuilder builder = new BooleanBuilder();
BooleanBuilder는 where문에 들어가는 조건들을 넣어주는 컨테이너라고 간주한다.
BooleanExpression expression = qGuestbook.title.contains(keyword);
원하는 조건은 필드 값과 같이 결합하여 생성한다.
builder.and(expression);
만들어진 조건은 where문에 and나 or같은 키워드와 결합시킨다.
Page<Guestbook> result = guestbookRepository.findAll(builder, pageable);
Booleanbuilder는 GuestbookRepository에 추가된 QuerydslPredicateExcuotr 인터페이스의 findAll()을 사용할 수 있다.
Querydsl을 사용하여 '제목 혹은 내용'에 특정한 키워드가 있고 'gno가 0보다 크다'인 조건을 처리(다중 항목 검색)
위에서 단일 항목 검색 테스트와 다른점은 exTitle과 exContent를 같은 BooleanExpression타입의 exAll로 결합하고
BooleanBuilder에 추가하는 점이있다. 이후 'gno가 0보다 크다'라는 조건을 추가하여 Booleanbuilder에 추가한다.
'코드로 배우는 스프링부트 웹 프로젝트' 카테고리의 다른 글
Springboot) 목록 처리 (0) | 2021.12.06 |
---|---|
Springboot) 서비스 계층과 DTO (0) | 2021.12.02 |
Springboot) 자동으로 처리되는 날짜/시간 설정 , JPA객체의 범위 (0) | 2021.12.02 |
Springboot)Thymeleaf 의 사용법 (0) | 2021.11.26 |
Springboot) MVC패턴 (0) | 2021.11.26 |