📦 Database/QueryDSL

Query Builder - Sort, Paging

신건우 2023. 5. 20. 20:18

💡 Sort

desc(), asc() : 일반 정렬
nullsLast(), nullsFirst() : null 데이터에 순서 부여

/**  
 * 회원 정렬 순서  
 * 1. 회원 나이 내림차순 (desc)
 * 2. 회원 이름 올림차순 (asc) 
 * 단 2에서 회원 이름이 없으면 마지막에 출력 (nulls test) 
 * */
@Test  
fun sort() {  
    val m: QMember = QMember.member  

    em.persist(Member(null, 100))  
    em.persist(Member("member5", 100))  
    em.persist(Member("member6", 100))  

    val result = queryFactory  
        .selectFrom(m)  
        .where(m.age.eq(100))  
        .orderBy(m.age.desc(), m.name.asc().nullsFirst())  
        .fetch()  

    val member5 = result.get(0)  
    val member6 = result.get(1)  
    val memberNull = result.get(2)  
    assertThat(member5.name).isEqualTo("member5")  
    assertThat(member6.name).isEqualTo("member6")  
    assertThat(memberNull.name).isNull()  

}

💡 Paging

count 쿼리가 실행되니 성능상 주의가 필요하다.

참고

실무에서 페이징 쿼리를 작성할 때, 데이터를 조회하는 쿼리는 여러 테이블을 조인해야 하지만,

count 쿼리는 조인이 필요없는 경우도 있다.

그런데 이렇게 자동화된 count 쿼리는 원본 쿼리와 같이 모두 조인을 해버리기 때문에 성능이 안 나올수 있다.

count 쿼리에 조인이 필요없는 성능 최적화가 필요하다면, count 전용 쿼리를 별도로 작성해야 한다.


조회 건 수 제한

/** @desc 페이징 - 조회 건수 제한 */
@Test  
fun paging1() {  
    val m: QMember = QMember.member  

    val result = queryFactory  
        .selectFrom(m)  
        .orderBy(m.name.desc())  
        .offset(1)  
        .limit(2)  
        .fetch()  

    assertThat(result.size).isEqualTo(2)  
}

전체 조회수가 필요할 때

/** @desc 페이징 - 전체 조회 수가 필요할 때 */@Test  
fun paging2() {  
    val m: QMember = QMember.member  

    val result = queryFactory  
        .selectFrom(m)  
        .orderBy(m.name.desc())  
        .offset(1)  
        .limit(2)  
        .fetchResults()  

    assertThat(result.total).isEqualTo(4)  
    assertThat(result.limit).isEqualTo(2)  
    assertThat(result.offset).isEqualTo(1)  
    assertThat(result.results).size().isEqualTo(2)  
}