escape-room

[QueryDSL] 소수점 반올림하기, ROUND 함수 사용하기 (ex.소수점 n번째 자리까지 반올림하기)

기매_ 2023. 5. 23. 22:05

테마 리스트에서 리뷰 평점을 출력하는데

SQL문이 그냥 ~ avg(reviews.rating) ~ 으로 나가기 때문에

저렇게 표시되는 것을 볼 수 있었다.

 

소수점 둘째짜리까지 나오도록 반올림해서 출력해보자 !

 

현재 상태는 select 절 안에 아래와 같이 입력되어 있다.

review.rating.avg().coalesce(-1.0)

시도 1. round() 함수 - 실패

review.rating.avg().coalesce(-1.0).round()

 

이와 같이 소수점 첫째자리에서 반올림된다.

round(2) 와 같이 파라미터를 넣어보려고 했지만 불가능했다.

SQL문도 round(coalesce(avg(reviews2_.rating), -1.0)) 으로 출력되는 것을 확인 ..


시도 2. Expressions.template() 메서드 사용 (데이터베이스 방언에 따라 패턴 설정) - 성공

Expressions.template(Double.class, "ROUND({0}, 2)", review.rating.avg().coalesce(-1.0))

성공 .. ! 

 

Expressions.template() 메서드를 사용하여 MySQL의 ROUND() 함수를 쿼리에 적용하였다. (본인이 설정해놓은 데이터베이스 방언에 따라 조금 다를 수 있음)

쿼리에 ROUND 함수를 적용하였고, {0} 자리에 review.rating.avg().coalesce(-1.0)을 삽입한다는 뜻이다.

나는 ROUND({0}, 2) 라고 했기 때문에 소수점 둘째 자리까지 반올림되어 표시되었다.

만약 n번째 자리에서 반올림하고 싶다면 ROUND({0}, 2) 에서 2 부분을 원하는대로 바꾸면 된다. (MySQL의 ROUND 함수 사용법 참고)

 

p6spy 로그를 보니 select 절에 내가 의도한 대로 아래와 같이 쿼리가 나간 것을 확인할 수 있었다 ! ㅎㅎ

round(coalesce(avg(reviews2_.rating), -1.0), 2)

혹시 위의 코드가 길어서 불편하다면

NumberExpression<Double> avgRating = review.rating.avg().coalesce(-1.0));
NumberExpression<Double> roundedAvgRating = Expressions.template(Double.class, "ROUND({0}, 2)", avgRating);

이런 식으로 메서드를 추출해도 된다..

 

import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;

NumberExpression<Double> avgRating = review.rating.avg();
NumberExpression<Double> roundedAvgRating = Expressions.template(Double.class, "ROUND({0}, 2)", avgRating);

queryFactory
    .select(new QThemeListDTO(
            theme.id,
            theme.name,
            roundedAvgRating))
    .from(theme)
    .leftJoin(theme.cafe, cafe)
    .leftJoin(theme, review.theme)
    .orderBy(roundedAvgRating.desc())
    .offset(pageable.getOffset())
    .limit(pageable.getPageSize())
    .fetch();

전체 코드

https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2

 

refactor: #21 - 리뷰 평점 반올림하여 소수점 둘째 자리로 출력되도록 변경 · maemae22/escape-room@5648c69

- Expressions.template() 메서드를 사용하여 ROUND(@@, 2) 함수를 적용함 - 정리 : https://maemae22.tistory.com/114

github.com