728x90
반응형
728x90
Querydsl DTO 조회
- Querydsl 사용하여 결과로 DTO를 반환할 때 사용하는 방법
프로퍼티 접근
- JPAQueryFactory를 사용하여 쿼리를 실행한 후 select 절에서 DTO의 getter 메서드를 호출
- Projections.bean()를 select절에 사용하여 Getter 호출을 위한 프로퍼티 작성
- DTO에 Getter와 Setter가 존재해야 함
- 필드명과 Getter, Setter 명이 같아야 함
//프로퍼티 접근
List<UserDTO> users = queryFactory
.select(Projections.bean(UserDTO.class,
QUser.user.name,
QUser.user.age))
.from(QUser.user)
.fetch();
필드 접근
- DTO의 필드에 직접 접근하여 값을 설정하는 방식
- Projections.fields()를 select절에 사용하여 DTO 필드에 값을 매핑
- 필드명이 쿼리에 사용되는 별칭과 같아야 함
- 필드명이 다르다면 as()를 사용해 별칭을 지정
//필드 접근
List<UserDTO> users = queryFactory
.select(Projections.fields(UserDTO.class,
QUser.user.name,
QUser.user.age))
.from(QUser.user)
.fetch();
//별칭 사용
List<UserDTO> users = queryFactory
.select(Projections.fields(UserDTO.class,
QUser.user.name.as("username"),
QUser.user.age))
.from(QUser.user)
.fetch();
생성자 접근
- DTO의 생성자를 통해 값을 설정하는 방식
- Projections.constructor()를 select절에 사용하여 DTO 생성자를 호출하여 객체를 생성
- 생성자가 필드의 순서와 타입에 맞춰 정의되어 있어야 함 -> 파라미터 이름이 다르거나 순서가 틀리면 매핑이 제대로 이루어지지 않을 수 있음
//생성자 접근
List<UserDTO> users = queryFactory
.select(Projections.constructor(UserDTO.class,
QUser.user.name,
QUser.user.age))
.from(QUser.user)
.fetch();
QueryProjection - DTO Q-Type 생성
- DTO에 직접 Querydsl의 Q타입을 생성하여 사용하는 방법
- DTO 클래스 생성자에 @QueryProjection 어노테이션을 사용
- select 절에 new 명령어를 통한 Q타입 DTO 객체를 생성하여 사용
- 장점: 컴파일 에러를 방지할 수 있음
- 단점: 엔티티가 Querydsl의 종속성을 가지게 됨
// QueryDSL
QUser user = QUser.user;
List<UserDTO> users = queryFactory
.select(new QUserDTO(user.name, user.age))
.from(user)
.fetch();
동적 쿼리
BooleanBuilder
- 여러 조건을 조합할 수 있도록 도와주는 유틸리티 클래스
- 여러 조건을 BooleanBuilder 객체에 정의해두고 where() 절에 BooleanBuilder 객체를 넣어 사용
- 해당 조건이 참인 경우만 조건에 추가 됨
주요 메서드
- and(): 조건을 AND로 결합
- or(): 조건을 OR로 결합
- reset(): 현재 조건을 초기화
- isEmpty(): 현재 조건이 비어 있는지 확인
- getValue(): 현재 조건을 BooleanExpression으로 반환
- add(): 기존의 조건을 추가
BooleanBuilder builder = new BooleanBuilder();
//and조건 - 유저 이름이 park이고 나이가 30 이상인 조건
builder.and(QUser.user.name.eq("park")).and(QUser.user.age.goe(30));
//or조건 - 유저 이름이 park이거나 나이가 30인 조건
builder.or(QUser.user.name.eq("park")).or(QUser.user.age.eq(30));
//AND로 조건을 추가 BooleanExpression
builder.add(QUser.user.name.eq("kim"));
//조건이 비어있는지 검사
builder.isEmpty()
//모든 조건 초기화
builder.reset();
//현재 조건을 BooleanExpression으로 반환
builder.getValue();
//사용 예시
public List<UserDTO> findUsers(String name, Integer age) {
QUser user = QUser.user;
BooleanBuilder builder = new BooleanBuilder();
if (name != null && !name.isEmpty()) {
builder.and(user.name.eq(name));
}
if (age != null) {
builder.and(user.age.eq(age));
}
return queryFactory
.select(Projections.bean(UserDTO.class, user.name, user.age))
.from(user)
.where(builder)
.fetch();
}
Where 다중 파라미터 사용
- where절의 다중 파라미터를 사용하여 검색 조건을 추가
- 기존 and 조건으로 추가
- 메서드를 통해 사용 시 재사용 가능
//null 값일 경우 해당 조건의 구문이 생성되지 않음
public List<UserDTO> findUsers(String name, Integer age) {
QUser user = QUser.user;
return queryFactory
.select(Projections.bean(UserDTO.class, user.name, user.age))
.from(user)
.where(name != null ? user.name.eq(name) : null, age != null ? user.age.eq(age) : null)
.fetch();
}
//메서드를 뽑아서 처리
public List<UserDTO> findUsers(String name, Integer age) {
QUser user = QUser.user;
return queryFactory
.select(Projections.bean(UserDTO.class, user.name, user.age))
.from(user)
.where(nameEq(name), ageEq(age))
.fetch();
}
private BooleanExpression nameEq(String nameCond) {
return nameCond != null ? QUser.user.name.eq(nameCond) : null;
}
private BooleanExpression ageEq(Integer ageCond) {
return ageCond != null ? QUser.user.age.eq(ageCond) : null;
}
SQL function 호출
- JPA와 같이 Dialect에 등록된 내용만 호출 가능
- Expressions.stringTemplate()을 사용하여 사용
- ansi 표준 함수들은 querydsl 이 기본적으로 상당 부분 내장 함수로 가지고 있음
QUser user = QUser.user;
//Expressions.stringTemplate 사용
queryFactory.select(user.name)
.from(user)
.where(user.name.eq(Expressions.stringTemplate("function('lower', {0})", user.name)))
//내장 함수로 처리
.where(user.name.eq(user.name.lower()))
서브 쿼리
- JPAExpression을 사용해 서브 쿼리 가능
//서브 퀄;
public List<Member> findMembersWithSubquery() {
QUser userSub = new QUser("userSub");
QUser user = QUser.user;
return queryFactory
.selectFrom(user)
.where(user.age.eq(
JPAExpressions
.select(userSub.age.max())
.from(userSub)
))
.fetch();
}
실전! Querydsl 강의 | 김영한 - 인프런 (inflearn.com) 강의 내용 참고
728x90
'백엔드 > Spring' 카테고리의 다른 글
[Spring] Jar & SpringBoot Jar (0) | 2024.09.28 |
---|---|
[Spring] 스프링 부트 (2) | 2024.09.27 |
[Spring] Querydsl (1) | 2024.09.25 |
[Spring] Spring Data Jpa 확장 기능 (0) | 2024.09.24 |
[Spring] 쿼리 메서드 (0) | 2024.09.23 |