Database

[Querydsl] 동적 정렬 sort를 위한 OrderSpecifier 클래스

로춘남 2023. 1. 19. 16:28
728x90

querydsl을 사용하면서 페이징 처리 및 검색기능 추가하고 있었다. 정렬 기능까지 추가하면서, 이것을 동적으로 처리 할 수는 없나? 라는 생각에 OrderSpecifier이라는 클래스를 알게되어 잠깐 기록을 남겨본다.

참고로 정적으로 정렬을 처리하기 위해선 ex) orderBy(user.userId.asc()) 이런식으로 처리를 할 수 있다.

하지만 이렇게 정적으로 박아두면 불편하지 않겠는가? Sort에 대한 부분을 설정해놨다면, 정렬에 대한 부분을 동적으로 활용하고 싶었다.

pageRequest에 페이징 처리가 되어있고, sort에 관한 정보를 가져오려고 했으나, getSort()를 읽지 못했다.

인자를 검색보니 OrderSpecifier 이라는 녀석을 이용해줘야하는걸 알아냈음.

 

명세서를 살펴보니,

OrderSpecifier에 필요한 인자들은 order, target, enum값이라는것을 확인 할 수 있었다.

Expression이 무엇인지 찾아보니, 정렬의 기준이 되는 컬럼의 Path라고 한다.

기준이 되는 엔티티와 엔티티 내부의 컬럼인데, 예를들어서 userSeq를 기준으로 정렬을 하고싶으면, User라는 엔티티에 userSeq가 속해있기때문에 User.userSeq라는 Path가 지정되게 된다.

코드로 대략 작성해보면서 흐름을 파악 할 수 있었다. Sort를 Stream으로 하나씩 하나씩 살펴보았음.

OrderSpecifier를 List타입으로 반환하였는데, 정렬의 기준이 1개 이상이 될 수 있기때문에 List으로 설정. direction 같은 경우 ASC 및 DESC 체크.

prop의 경우에는 정렬할 기준의 변수를 읽어왔으며, PathBuilder를 통해 정렬의 기준을 설정했다. 코드에보면 Object클래스에 roma라는 변수를 설정했고, 이제 roma라는것을 기준으로 정렬이 잡히게 된다.

 

그렇다면 최종적으로 orderSpecifiers라는 Array에는 direction, 그리고 변수에 따른 정렬 기준이 add 되게 된다.

아마 new OrderSpecifier(ASC, user.userSeq) 라는 기준으로 담기가 될 것이다.

해당 부분을 querdsl orderby에 적용시키니 원하는대로 정렬이 되는것을 확인 할 수 있었다.

추가적으로 살펴보니 Expression.path(type, parent, property)의 형태로도 사용 할 수 있는것 같다.

아마 Path 클래스를 사용해야되는거 같은데, pageDTO라는 식으로 페이징 및 정렬처리를 따로 설정해놓으면, pathBuilder만으로 동적 정렬을 쉽게 구현 할 수 있겠구나라는 생각이 들었다.

728x90