Spring/스프링 데이터 JPA
[스프링 데이터 JPA] 스프링 데이터 Common 10. QueryDSL
주멘이
2021. 1. 16. 22:05
메서드 이름 기반의 자동 쿼리 만들기 방식은 너무 알아보기 힘들다는 단점이 있다.
findByFirstNameIngoreCaseAndLastNameStartsWithIgnoreCase(String firstName, String lastName)
여러 쿼리 메서드는 대부분 두 가지 중 하나
- Optional findOne(Predicate): 이런 저런 조건으로 무언가 하나를 찾는다.
- List|Page|.. findAll(Predicate): 이런 저런 조건으로 무언가 여러 개를 찾는다
- QuerydslPredicateExecutor 인터페이스
QuerydslPredicateExecutor (Spring Data Core 2.4.3 API)
Iterable findAll(com.querydsl.core.types.Predicate predicate, com.querydsl.core.types.OrderSpecifier ... orders) Returns all entities matching the given Predicate applying the given OrderSpecifiers.
docs.spring.io
QueryDSL(Domain Specific Language)
Querydsl - Unified Queries for Java
Unified Queries for Java. Querydsl is compact, safe and easy to learn.
- 타입 세이프한 쿼리 만들 수 있게 도와주는 라이브러리
- JPA, SQL, MongoDB, JDO, Lucene, Collection 지원
- QueryDSL JPA 연동 가이드
스프링 데이터 JPA + QueryDSL
- 인터페이스: QuerydslPredicateExecutor
- 구현체: QuerydslPredicateExecutor
연동 방법
- 기본 리포지토리 커스터마이징 안 했을 때. (쉬움)
- 기본 리포지토리 커스타마이징 했을 때. (헤맬 수 있으나... 제가 있잖습니까)
의존성 추가
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<!-- 빌드 설정 -->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
- 스프링 부트가 의존성을 관리해주므로 버전을 명시하지 않아도 된다
- apt는 querydsl이 entity를 보고 query용 specific language를 만들어 주는 모듈이다.
- 의존성을 다 추가한 후, Maven compile을 실행하면 target/generated-sources/java에 클래스가 생성된다.
PostRepository에 QuerydslPredicateExecutor 상속하기
public interface PostRepository extends YourRepository<Post, Long>, QuerydslPredicateExecutor<Post> {
Page<Post> findByTitleContains(String title, Pageable pageable);
long countByTitleContains(String title);
}
테스트 코드
@Test
public void querydslTest() {
//Given
Post post = new Post();
post.setTitle("post querydsl");
postRepository.save(post.publish());
//When
Predicate predicate = QPost.post.title.contains("query");
Optional<Post> one = postRepository.findOne(predicate);
//Then
assertThat(one).isNotEmpty();
}