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