Spring Data JPA #4 단순 게시글 처리 #4 Querydsl을 이용한 동적 SQL의 처리

2021. 10. 6. 16:31JAVA/Spring

이전글

https://yonghwankim-dev.tistory.com/136

 

Spring Data JPA #4 단순 게시글 처리 #3 @Query 애노테이션 이용하기

이전글 https://yonghwankim-dev.tistory.com/135 Spring Data JPA #4 단순 게시글 처리 #2 쿼리 메서드의 페이징 처리와 정렬 이전 글 https://yonghwankim-dev.tistory.com/134 Spring Data JPA #4 단순 게시글..

yonghwankim-dev.tistory.com

 

본 글은 스타트 스프링 부트 도서의 내용을 복습하기 위해 작성된 글입니다.

 

개요

쿼리를 처리하다 보면 다양한 상황에 맞게 쿼리를 생성하는 경우가 많습니다. 대표적인 케이스가 다양한 검색 조건에 대해서 쿼리를 실행해야 하는 경우라고 할 수 있습니다. 쿼리 메소드나 @Query를 이용하는 경우에 개발 속도는 좋지만 고정적인 쿼리만을 생상합니다. 따라서 동적인 상황에 대한 처리를 위해서 Querydsl이라는 것을 이용합니다.

 

Querydsl이란 무엇인가?

Querydsl의 dsl은 'Domain Specific Language'의 약자로 특정 도메인 객체를 조회한다는 의미입니다. (Hibernate의 경우 Criteria라는 것을 주로 애용했지만, Spring Data JPA를 이용하는 경우에는 Querydsl이 편리합니다.)

 

Querydsl 이용하기 위한 과정

  1. pom.xml의 라이브러리와 Maven 설정의 변경 및 실행
  2. Predicate의 개발
  3. Repository를 통한 실행

1. Querydsl을 위한 준비

Querydsl은 Java를 이용해서 쿼리 조건을 처리할 때 사용하는 라이브러리입니다. 개발자는 SQL을 직접 처리하지 않고, Querydsl을 이용해서 필요한 조건을 처리하는 Java 코드를 생성하고, Repository를 통해서 이를 처리합니다.

 

구글 브라우저에 querydsl maven 검색

https://mvnrepository.com/artifact/com.querydsl

 

pom.xml에 다음과 같은 <dependency> 추가

		<dependency>
		  <groupId>com.querydsl</groupId>
		  <artifactId>querydsl-apt</artifactId>
		  <version>${querydsl.version}</version>
		  <scope>provided</scope>
		</dependency>
		
		<dependency>
		  <groupId>com.querydsl</groupId>
		  <artifactId>querydsl-jpa</artifactId>
		  <version>${querydsl.version}</version>
		</dependency>

pom.xml에 <plugin> 추가

			<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>

 

프로젝트(boot03) 오른쪽 버튼 클릭 -> Run As -> Maven Build

target/generated-sources/java/org/zerock/domain/QBoard.java 생성확인

메이븐에 <plugin>으로 추가된 코드 생성기는 Board.java 파일이 변경되면 자동으로 QBoard.java를 생성해 주므로 한 번만 세팅해주면 이후에는 별도의 작업이 필요치 않습니다.

 

2. Predicate 준비

Predicate는 '이 조건이 맞다'고 판단하는 근거를 함수로 제공하는 것입니다. Repository에서 Predicate를 파라미터로 전달하기 위해서는 QueryDslPredicateExecutor<T> 인터페이스를 Repository에 추가해야 합니다.

 

QueryDslPredicateExecutor<T> 인터페이스의 메서드

메서드 설명
long count(Predicate) 데이터의 전체 개수
boolean exists(Predicate) 데이터의 존재 여부
Iterable<T> findAll(Predicate) 조건에 맞는 모든 데이터
Page<T> findAll(Predicate) 조건에 맞는 모든 데이터
Iterable<T> findAll(Predicate, Sort) 조건에 맞는 모든 데이터와 정렬
T findOne(Predicate) 조건에 맞는 하나의 데이터

 

2.1 Repository 변경

Repository 인터페이스에는 QueryDslPredicateExecutor<T> 인터페이스를 상속하도록 추가해주어야 합니다.

 

org.zerock.persistence.BoardRepository

public interface BoardRepository extends CrudRepository<Board, Long>, QuerydslPredicateExecutor<Board>{
		
}

 

3. Predicate 생성 및 테스트

org.zerock.Boot3ApplicationTests 일부

	@Disabled
	@Test
	void testPredicate() {
		String type = "t";
		String keyword = "17";
		
		BooleanBuilder builder = new BooleanBuilder();
		
		QBoard board = QBoard.board;
		
		if(type.equals("t"))
		{
			builder.and(board.title.like("%"+keyword+"%"));
		}
		
		// bno>0
		builder.and(board.bno.gt(0));
		
		Pageable pageable = PageRequest.of(0, 10);
		
		Page<Board> result = repo.findAll(builder, pageable);
		
		System.out.println("PAGE SIZE: " + result.getSize());
		System.out.println("TOTAL PAGES: " + result.getTotalPages());
		System.out.println("TOTAL COUNT: " + result.getTotalElements());
		System.out.println("NEXT: " + result.nextPageable());
		
		List<Board> list = result.getContent();
		
		list.forEach(b -> System.out.println(b));		
	}

동적 쿼리에 필요한 조건을 and() 등을 이용해서 추가합니다. QBoard는 Board의 속성을 이용해서 다양한 SQL에 필요한 구문을 처리할 수 있는 기능이 추가된 형태이므로 like()나 get() 등을 이용해서 원하는 SQL을 구성하는 데 도움을 줍니다.

 

위와 같이 Predicate는 필요한 곳에 생성하는 방식을 이용하기도 하지만, 별도의 클래스 등으로 만들어서 사용할 수 있습니다.

 

References

스타트 스프링 부트, 구멍 가게 코딩단 저