inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Trong thực tế! Phát triển ứng dụng quản lý thư viện với Kotlin và Spring Boot (tái cấu trúc dự án Java)

Bài học 40. Tái cấu trúc UserLoanHistoryRepository thành Querydsl

QueryDSL Pageable 질문

1028

Tony

8 câu hỏi đã được viết

0

안녕하세요, 강의 잘 듣고 있습니다.

동적 쿼리 구성을 하려다가

기존에

findByName(name: String, pageable: Pageable)

이라는 함수를 써서 쉽게 sorting 및 pagination 을 구현했는데요.

영상에서처럼 검색 조건이 늘어나서 QueryDSL 로 바꾸려고 하는데, 혹시 pageable 을 쉽게 QueryDSL 에서 구현하는 방법이 있을까요?

spring kotlin spring-boot java refactoring

Câu trả lời 2

5

lannstark

안녕하세요~! Tony님!!! ㅎㅎㅎ 아이고~~ 좋은 질문이십니다!!!

우선 간단하게 Pageable 을 바로 사용하기는 어려워 다음과 같이 limit / offset으로 치환해주어야 합니다!

fun findAll(pageable: Pageable): List<Book> {
  return queryFactory.select(book)
    .from(book)
    .limit(pageable.pageSize.toLong())
    .offset(pageable.offset)
    .fetch()
}

 

하지만~~ Kotlin의 Extension function을 활용하면 다음과 같은 유틸성 함수를 만들 수 있고 모든 코드에서 Pageable을 바로 사용하는 것처럼 쓸 수 있습니다!

// 유틸 파일에 모아두기!
fun <T> JPAQuery<T>.withPageable(pageable: Pageable): JPAQuery<T> {
  return this.limit(pageable.pageSize.toLong())
    .offset(pageable.offset)
}

// 이제 다른 모든 Repository에서는 다음과 같이 활용 가능
fun findAll(pageable: Pageable): List<Book> {
  return queryFactory.select(book)
    .from(book)
    .withPageable(pageable)
    .fetch()
}

 

위와 같이 확장함수를 잘 활용하 매우 편리한 개발이 가능하더라고요!! 좋은 질문 감사합니다 ㅎㅎㅎㅎ 또 궁금하신 점 있으시면 편하게 질문 주세요~! 감사합니다! 😊

0

Tony

친절한 답변 너무 감사합니다!

제가 찾아보다보니까 이런 방법도 있던데, 혹시 많이 사용하는 방법일까요?

QuerydslRepositorySupport 를 상속해서 querydsl (getQuerydsl()) 을 가지고 applyPagination 을 하면 따로 유틸성 함수 추가 없이 사용이 가능하더라구요..!

 

@Component
class ContentQuerydslRepository<T>(
    private val queryFactory: JPAQueryFactory
) : QuerydslRepositorySupport(Content::class.java) {

    fun findContent(
        title: String?, dtype: String?,
        category: String?, pageable: Pageable
    ): List<Content> {
        val query = queryFactory
            .selectFrom(content)
            .where(
                title?.let { content.title.contains(title) },
                dtype?.let { content.dtype.eq(ContentType(dtype)) },
                category?.let { content.category.eq(ContentCategory(category)) },
            )

        return querydsl!!.applyPagination(pageable, query).fetch()

    }
}

1

lannstark

저는 개인적으로 많이 사용하지 않습니다! 그 이유는 1) 상속하는 것 자체가 약간 번거롭기도 하고, 2) 도메인 클래스 (Class<?>)를 넣어줘야 하는데 쿼리가 복잡해질 수록 N개의 Entity가 사용되기도 하기 때문이에요!!

유틸성 함수 같은 경우는 한 번만 추가하면 계속 사용할 수 있다보니, 크게 불편함을 느끼지 못하고 있습니다 ㅎㅎㅎㅎㅎ

0

Tony

아 그런 문제가 있을 수 있겠군요. 답변 감사합니다!

안녕하세요 혹시 프론트 코드 제공받을 수 있을까요?

0

68

2

실행이 안되네요

0

66

2

프론트 영역 보는법

0

51

2

companion object

0

78

2

Custom 레프직토리 형식

0

57

2

Querydsl 도입

0

67

2

fetch join DISTINCT 중복제거

1

83

2

표준 예외와 커스텀 예외 사용 전략 질문

0

86

3

이 질문이 왜 없는지 이해가 안 되지만 문제 인식 및 해결 방법 남깁니다.

1

177

2

테스트를 위한 코드

1

105

2

프로젝트 실행 에러

0

151

2

PDF 문서에 오타가 있어서 알려드립니다.

1

102

1

enum질문

1

86

1

테스트 후 AfterEach 함수에서 나오는 쿼리

0

136

2

테스트 fixture

1

210

2

./gradlew test 실행시 인식할수 없다고 뜹니다.

0

140

1

test 코드 실행시 경고가 발생합니다.

0

140

1

13강 User Kotlin 변환중

2

169

3

'추가 - 코프링과 플러그인' 강의 7:46 allopen 관련 질문

2

174

1

-

0

141

2

4:28 build.gradle 수정 시 kotlin-reflect관련 implementation 추가 해야할까요?

0

312

3

junit import 불가

0

272

3

테스트 코드와 관련하여 질문이 있습니다.

1

218

1

hibernate가 select를 두번 하는 이유

0

240

1