🔥 TIL - Day 65 Querydsl Group by


QuerydslのGroup byを検索すると、注目すべき話題が見つかりました.簡単に片付けて
本プロジェクトでは,言語別に個数を把握することが求められる.
最初に作成したクエリーは次のとおりです.
    @Override
    public List<ReviewRequestLanguageCount> getReviewRequestLanguageCountGroupByLanguage() {
        List<Tuple> result = query.select(reviewRequest.languageName, reviewRequest.id.count())
                .from(reviewRequest)
                .groupBy(reviewRequest.languageName)
                .fetch();

        return result.stream().map(
                r -> new ReviewRequestLanguageCount(r.get(0, String.class), r.get(1, Long.class))
        ).collect(Collectors.toList());
    }
言語名(languageName)を使用してGroup byのターゲットを計算できるようになりました.発生したクエリーも予想外だった.

こうして実施が完了し、存在する可能性のある話題を探すためにグーグルが検索したが、案の定、達人たちの話題が出てきた.

📌 (MySQL)Group byで自動ソート?話題


クエリに問題はありませんが、MySqlからGroup byを使用すると、自動的にソートされます.ただし、グループはソートする必要はありません.この無駄な仕事を取り除かなければならない.
一般的なMySqlは上記の問題をorder by nullに解決した.
(明確に並べ替えていないことを示す?)
Querydslはorder by nullを直接使用することは許されないが、OrderSpecifierを使用してソート動作をカスタマイズすることができ、同様に直接実現することができる.
jojolduのコードが使用されています.
public class OrderByNull extends OrderSpecifier {
    public static final OrderByNull DEFAULT = new OrderByNull();

    private OrderByNull() {
        super(Order.ASC, NullExpression.DEFAULT, NullHandling.Default);
    }
}
このようにNull(NullExpression.DEFAULT)のソートをGroupbyを実行する場所に適用すればよい.
    @Override
    public List<ReviewRequestLanguageCount> getReviewRequestLanguageCountGroupByLanguage() {
        List<Tuple> result = query.select(reviewRequest.languageName, reviewRequest.id.count())
                .from(reviewRequest)
                .groupBy(reviewRequest.languageName)
                // 적용
                .orderBy(OrderByNull.DEFAULT)
                .fetch();

        return result.stream().map(
                r -> new ReviewRequestLanguageCount(r.get(0, String.class), r.get(1, Long.class))
        ).collect(Collectors.toList());
    }
クエリの結果からorder by null ascが表示されます.

📌 リファレンス


Querydslグループの最適化
https://jojoldu.tistory.com/477