QueryDSL - 쿼리문 작성하기

김희영·2025년 11월 7일

spring

목록 보기
21/26

다음 조건을 만족하는 값이 있는지 확인 하기

jpaQuery
            .selectOne()
            .from(테이블명)
            .where(
                조건
            ).fetchFirst() != null

-> 특정 조건에 해당하는 열을 가져오는데, 1 로 가져옴
-> 있을 경우 1이 리턴, 없으면 null이 리턴 됨
-> != null 로 참/거짓 값을고 변환하여 리턴

조회에 페이징 기능

override fun findQById(
        id: Long,
        pageable: Pageable
    ): Page<Member> {
    
        val member = QMember.member

        //content
        val result =jpaQuery
            .selectFrom(member)
            .where(조건)
            .offset(pageable.offset)               //시작
            .limit(pageable.pageSize.toLong())     //끝
            .fetch()
            
        //total count
        val totalCount= jpaQuery
            .select(member.count())
            .from(member)
            .where(조건)
            .fetchOne() ?: 0L
        
        return PageImpl(result, pageable, totalCount)
    }

리턴값이 Page라 조회가 2번 필요하다. (데이터랑, 페이지 관련 메타데이터)

+) JPA로 페이징 쓰기
fun findById(Id: Long, pageable: Pageable): Page<엔티티명> 끝.

근데 total Count를 조회하는 건 힘든 일이다.

오래 걸릴 수도 있고, 비효율적이다.
그래서 PageableExecutionUtils을 사용한다. 이러면 이제 필요할 때만 조회를 할 수 있다.

PageableExecutionUtils.getPage(조회한 데이터,pageable){totalCount 구하는 쿼리}

조회에 정렬 추가

override fun findQByIdDesc(id: Long): List<Member> {
        val member = QMember.member

        return jpaQuery
            .selectFrom(member)
            .where(조건)
            .orderBy(member.id.desc())
            .fetch()
    }

근데 사실 orderBy(member.id.desc()) 이건 OrderSpecifier를 받는 거라 직접 member.id.desc() 이렇게 적지 말고 따로 선언 해서 넣을 수 있긴하다.

-> .orderBy(member.id.desc()) 여기에 어떤 걸 기준으로 오름차순/내림차순 할 건지 정함

Page에 정렬 넣어서 하기

정렬을 pageable에 다 넣고 할 수도 있다.

val pageable = PageRequest.of(
            0, 2, //오프셋과 페이지 사이즈
            Sort.by("id").descending()
                .and(Sort.by("username").ascending())
        )

그리고 이걸로 조회도 가능

 override fun findQByID(
        Id: Long,
        pageable: Pageable
    ): Page<Member> {
        val member = QMember.member

        // content 쿼리
        val query = jpaQuery
            .selectFrom(member)
            .where(조건)

        //정렬 기준을 정해줌
        pageable.sort.forEach { order ->
            when(order.property){
                "id" -> query.orderBy(if(order.isAscending) member.id.asc() else member.id.desc())
                "nickname" -> query.orderBy(if(order.isAscending) member.nickname.asc() else member.nickname.desc())
                "username" -> query.orderBy(if(order.isAscending) member.username.asc() else member.username.desc())
            }
        }

        //마저 쿼리
        val content = query
            .offset(pageable.offset)
            .limit(pageable.pageSize.toLong())
            .fetch()
        
        //리턴
        return PageableExecutionUtils.getPage(content, pageable) {
            jpaQuery
                .select(member.count())
                .from(member)
                .where(member.username.contains(username))
                .fetchOne() ?: 0L
        }
    }

검색하기

빌더를 이용해서 조건을 추가해서 검색하기도 가능하다.


        val builder = BooleanBuilder()?.apply {
        //검색 타입에 따라 어디서 검색할지 넣기
            when(kwType){
                "USERNAME" -> this.and(member.username.contains(kw))
                "NICKNAME" -> this.and(member.nickname.contains(kw))
                "ALL" -> {
                    this.and(member.username.contains(kw).or(
                        member.nickname.contains(kw)
                    ))
                }
            }

        }

      이후 where()에 builder 넣으면 됨

profile
내는 반드시 개발자가 되고 말것어

0개의 댓글