1. 동적 쿼리(Dynamic Query)란?
동적 쿼리란 입력값에 따라 where 절의 조건이 유동적으로 바뀌는 쿼리를 의미한다.
예시
- 검색 조건으로 이름, 나이 중 하나만 입력한 경우
- 사용자 선택에 따라 조건이 유동적으로 적용되는 UI 필터
QueryDSL은 이런 동적 조건을 유연하게 처리할 수 있는 DSL( Domain Specific Language, 특정 영역(도메인)에 특화된 언어 )을 제공한다.
2. BooleanBuilder 방식
예시 코드
private List<Member> searchMember1(String usernameCond, Integer ageCond) {
BooleanBuilder builder = new BooleanBuilder();
if (usernameCond != null) {
builder.and(member.username.eq(usernameCond));
}
if (ageCond != null) {
builder.and(member.age.eq(ageCond));
}
return queryFactory
.selectFrom(member)
.where(builder)
.fetch();
}
설명
- BooleanBuilder는 Querydsl에서 제공하는 조건 누적용 빌더 클래스다.
- .and(), .or() 등을 이용해 조건을 프로그래밍 흐름에 따라 동적으로 추가할 수 있다.
- 조건이 복잡하고 동적으로 조립되는 경우에 유리하다.
3. where 다중 파라미터 방식
예시 코드
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(usernameEq(usernameCond), ageEq(ageCond))
.fetch();
}
private BooleanExpression usernameEq(String usernameCond) {
return usernameCond != null ? member.username.eq(usernameCond) : null;
}
private BooleanExpression ageEq(Integer ageCond) {
return ageCond != null ? member.age.eq(ageCond) : null;
}
설명
- where() 절에 여러 조건을 메서드로 전달
- 각 조건 메서드는 BooleanExpression을 반환하며, null은 자동으로 무시됨
- 조건 메서드를 별도로 관리하므로 재사용성과 가독성이 뛰어남
조합 메서드 예시
private BooleanExpression allEq(String usernameCond, Integer ageCond) {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
4. 두 방식의 차이점 및 비교
항목 | BooleanBuilder | where 다중 파라미터 |
가독성 | 낮음 (조건 많아지면 복잡) | 높음 (조건 메서드 분리 가능) |
재사용성 | 낮음 | 높음 (메서드 재사용 가능) |
유연성 | 높음 (복잡한 로직 조합) | 중간 (직접 and/or 명시 필요) |
코드 길이 | 상대적으로 김 | 상대적으로 짧음 |
null 처리 | 직접 체크 필요 | 자동 무시 (내부에서 처리됨) |
- BooleanBuilder는 복잡한 조건 조합이 필요한 경우 유리
- BooleanExpression 방식은 구조화된 조건 처리에 유리
5. 추가적으로 알아야 할 개념
1. BooleanBuilder vs BooleanExpression
항목 | BooleanBuilder | BooleanExpression |
타입 | 빌더 객체 | 조건 객체 |
조립 방식 | .and(), .or()로 누적 | 메서드 체이닝 또는 where에 직접 전달 |
장점 | 유연한 조건 구성 | 재사용 및 가독성 좋음 |
2. Null 조건 자동 무시
.where(null, condition1, condition2)
- null 값은 자동으로 무시됨 → 안전한 쿼리 구성 가능
3. 조합 메서드로 응집도 있는 쿼리 구성
.where(allEq(username, age))
- 조합된 조건을 하나의 메서드로 추상화 → 재사용성과 응집도 향상
4. 기타 Querydsl 팁
메서드 | 설명 |
fetch() | 리스트 반환 |
fetchOne() | 단건 조회 (0건: null, 2건 이상: 예외) |
fetchFirst() | 첫 번째 레코드만 반환 |
username.eq("홍길동") | SQL의 username = '홍길동'과 동일한 의미 |
BooleanExpression이 null이면 | where 절에서 자동 무시됨 |
6. 정리
방식 | 장점 | 단점 | 사용 권장 상황 |
BooleanBuilder | 복잡한 조건 조합 가능 | 가독성 낮음, null 수동 체크 필요 | 복잡한 검색 조건, UI 필터 다양할 때 |
where 다중 파라미터 | 코드 깔끔, 조건 재사용 가능, null 자동 무시 | 메서드 수 많아질 수 있음 | 단순하거나 재사용 가능한 조건 처리 시 |
반응형
'Backend > JPA' 카테고리의 다른 글
Querydsl - 사용자 정의 JPA 리포지토리 설계 및 구현 (0) | 2025.04.11 |
---|---|
QueryDSL - 한 번의 SQL 쿼리로 여러 건의 데이터를 일괄 수정 또는 삭제하는 방법 (벌크 연산) (0) | 2025.03.25 |
QueryDsl - 프로젝션을 DTO 결과로 반환하는 방법과 개념 (0) | 2025.03.17 |
JPA (Spring Data JPA) - Spring Boot 3+ QueryDSL 및 JPA 기본 설정, p6spy 로깅 방법 (0) | 2025.03.13 |
JPA (Spring Data JPA) - SimpleJpaRepository(JPA Repository 기본 구현체) 파악해보기 (0) | 2025.03.13 |