Spring JPA와 Hibernate의 소스 코드를 파고 들자 나는 내 문제에 대한 해결책을 찾을 수 있었다. 나는 이것이 이것을 해결하는 좋은 방법이 아니라고 확신하지만, 내가 찾을 수있는 유일한 방법이다.
SingularAttributePath
클래스를 확장하여 쿼리 순서 부분에 대한 래퍼를 구현했습니다. 이 클래스에는 실제 쿼리에 삽입되는 문자열을 생성하는 render 메서드가 있습니다. 내 구현은 다음과 같습니다.
@Override
public String render(RenderingContext renderingContext) {
String render = super.render(renderingContext);
render = "MYPACKAGE.NSORT(" + render + ")";
return render;
}
다음으로 SimpleJpaRepository 클래스의 주문 변환 기능을 확장했습니다. 기본적으로이 작업은 QueryUtils.toOrders(sort, root, builder)
을 호출하여 수행됩니다.그러나 메서드를 호출하는 것이 불가능하기 때문에 재정의하는 것이 불가능하므로 결국 toOrder
메서드를 호출하고 결과를 원하는대로 변경했습니다.
이것은 결과의 모든 주문을 SingularAttributePath
클래스의 맞춤 구현으로 바꾸는 것을 의미합니다. 추가로 나는 클래스에 의해 사용되는 클래스 인 Sort
을 래핑 된 것과 그렇지 않은 것 (NaturalOrder라고 불리는 것)을 제어 할 수 있도록 확장했다. 하지만 잠시 후에 그걸 보겠습니다. 내 구현은 query.orderBy(resultlist)
를 호출하여 (일부 검사는 탈락된다)
// Call the original method to convert the orders
List<Order> orders = QueryUtils.toOrders(sort, root, builder);
for (Order order : orders) {
// Fetch the original order object from the sort for comparing
SingularAttributePath orderExpression = (SingularAttributePath) order.getExpression();
Sort.Order originalOrder = sort.getOrderFor(orderExpression.getAttribute().getName());
// Check if the original order object is instantiated from my custom order class
// Also check if the the order should be natural
if (originalOrder instanceof NaturalSort.NaturalOrderm && ((NaturalSort.NaturalOrder) originalOrder).isNatural()){
// replace the order with the custom class
Order newOrder = new OrderImpl(new NaturalSingularAttributePathImpl(builder, expression.getJavaType(), expression.getPathSource(), expression.getAttribute()));
resultList.add(newOrder);
}else{
resultList.add(order);
}
}
return resultList;
다음 쿼리에 추가됩니다 반환 목록이 가까이 보인다. 백엔드 용입니다.
랩핑 조건을 제어하기 위해 에 사용 된 Sort
클래스를 확장했습니다 (몇 줄을 뒤에서 언급 했음). 추가하고자하는 유일한 기능은 방향 열거 형에 4 가지 유형이 있다는 것입니다.
- ASC (기본 오름차순)
- DESC (기본 내림차순)
- NASC (정상 오름차순)
- NDESC (정상 내림차순)
마지막 두 값 만 자리로서 작용한다. 조건에 사용되는 isNatural
부울 (확장 된 Order
클래스의 변수)을 설정합니다. 쿼리가 변환 될 때 기본 변형으로 다시 매핑됩니다.
public Direction getNativeDirection() {
if (this == NaturalDirection.NASC)
return Direction.ASC;
if (this == NaturalDirection.NDESC)
return Direction.DESC;
return Direction.fromString(String.valueOf(this));
}
는 마지막으로 나는
PageableHandlerMethodArgumentResolver
에 의해 사용되는
SortHandlerMethodArgumentResolver
를 교체했다. 이 유일한 작업은 내
NaturalSort
클래스의 인스턴스를 만들고 기본값
Sort
클래스 대신 Pageable 객체에 전달하는 것입니다.
결과적으로 결과가 정렬되는 동안 동일한 REST 끝점을 호출 할 수 있습니다.
Default Sorting
/api/v1/items?page=0&size=20&sort=name,asc
Natural Sorting
/api/v1/items?page=0&size=20&sort=name,nasc
이 솔루션은 자연 분류 및 JPA와 관련하여 동일하거나 유사한 문제가있는 사용자에게 도움이되기를 바랍니다. 질문이나 개선 사항이 있으면 알려주십시오.
이름은 사용자가 설정하므로 실제로는 옵션이 아닙니다. 그래서 저는 그 정보의 내용에 아무런 영향을 미치지 않습니다. –
findAll 메서드에서 생성 된 쿼리에 원시 SQL을 추가하는 방법이 있습니까? –
@RobinHermans 그래서, 미리 정의 된 형식의 입력 된 텍스트가 있습니까? 의미, 그 사용자가 입력 할 수 있습니다 _ "이것은 두 번째 그룹입니다"_ 와야합니다 _ "이것은 열 번째 그룹입니다"_ 정렬 순서에? –