우선 Querydsl을 사용하기 위해서는 인터페이스를 만들고, 구현체를 만들고, Repository에 상속한다
1. Repository (SpringDataJpa, Querydsl 2개를 상속받았다)
@Repository
interface MemberRepository : JpaRepository<Member, Long>, MemberRepositoryCustom {
}
2. 인터페이스
interface MemberRepositoryCustom {
fun search(condition: MemberSearchCondition): List<MemberTeamDto>
fun searchPageSimle(condition: MemberSearchCondition, pageable: Pageable): Page<MemberTeamDto>
fun searchPageComplex(condition: MemberSearchCondition, pageable: Pageable): Page<MemberTeamDto>
}
3. 구현부
//MemberRepositoryCustomImpl : MemberRepositoryCustom
override fun searchPageSimle(condition: MemberSearchCondition, pageable: Pageable): Page<MemberTeamDto> {
//페이징쿼리
val content = queryFactory
.select(QMemberTeamDto(
member.id.`as`("memberId"),
member.username,
member.age,
team.id.`as`("teamId"),
team.name.`as`("teamName")
))
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.username),
teamNameEq(condition.teamName),
ageGoeEq(condition.ageGoe),
ageLoeEq(condition.ageLoe)
)
.offset(pageable.offset)
.limit(pageable.pageSize)
.fetch()
//카운트 쿼리
val totalSize = queryFactory
.selectFrom(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.username),
teamNameEq(condition.teamName),
ageGoeEq(condition.ageGoe),
ageLoeEq(condition.ageLoe)
)
.fetch().size
return PageImpl(content, pageable, totalSize)
}
//`PageableExecutionUtils.getPage()`로 최적화
override fun searchPage_최적화(condition: MemberSearchCondition, pageable: Pageable): Page<MemberTeamDto> {
val content = queryFactory
.select(QMemberTeamDto(
member.id.`as`("memberId"),
member.username,
member.age,
team.id.`as`("teamId"),
team.name.`as`("teamName")
))
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.username),
teamNameEq(condition.teamName),
ageGoeEq(condition.ageGoe),
ageLoeEq(condition.ageLoe)
)
.offset(pageable.offset)
.limit(pageable.pageSize)
.fetch()
val countQuery = queryFactory
.selectFrom(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.username),
teamNameEq(condition.teamName),
ageGoeEq(condition.ageGoe),
ageLoeEq(condition.ageLoe)
)
return PageableExecutionUtils.getPage(content, pageable, { countQuery.fetch().size })
}
- 스프링 데이터 라이브러리가 제공
- count 쿼리가 생략 가능한 경우 생략해서 처리
- 페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 때
- 마지막 페이지 일 때 (offset + 컨텐츠 사이즈를 더해서 전체 사이즈 구함)
::: aside 💡
Controller에서 사용
:::
@RestController
@RequiredArgsConstructor
class MemberController(private val memberRepository: MemberRepository) {
@GetMapping("/v2/members")
fun searchMemberV2(condition: MemberSearchCondition, pageable: Pageable): Page<MemberTeamDto> {
return memberRepository.searchPageComplex(condition, pageable)
}
}
'Programing > Spring Boot' 카테고리의 다른 글
| 스프링부트 스케줄러가 여러번 실행된다면? @SchedulerLock 사용법 (0) | 2023.07.06 |
|---|---|
| SpringBoot @RequestBody 데이터 선택적으로 받기 (0) | 2023.07.04 |
| Scanner 테스트코드 작성하기 System.setIn() (0) | 2023.07.02 |
| Querydsl 동적 쿼리 사용하는 2가지 방법 (Builder, where절 파라미터) (0) | 2023.07.01 |
| SpringBoot 테스트코드 작성시 Security 권한 무시하는법 @PreAuthorize우회 하기 (0) | 2023.07.01 |