Java 如何对Spring数据Jpa使用自然排序

Java 如何对Spring数据Jpa使用自然排序,java,oracle,hibernate,spring-data-jpa,natural-sort,Java,Oracle,Hibernate,Spring Data Jpa,Natural Sort,我有一个要订购的表列。问题是列值同时包含数字和文本。例如,结果现在按如下顺序排列 1. group one 10. group ten 11. group eleven 2. group two 但是我希望结果是自然排序的,像这样 1. group one 2. group two 10. group ten 11. group eleven @Override public String render(RenderingContext renderingContext) { Strin

我有一个要订购的表列。问题是列值同时包含数字和文本。例如,结果现在按如下顺序排列

1. group one
10. group ten
11. group eleven
2. group two
但是我希望结果是自然排序的,像这样

1. group one
2. group two
10. group ten
11. group eleven
@Override
public String render(RenderingContext renderingContext) {
  String render = super.render(renderingContext);
  render = "MYPACKAGE.NSORT(" + render + ")";
  return render;
}
在查看Spring配置时,我似乎找不到一个允许您这样做的选项。我使用Spring Pageable类来设置我的订单字段和方向,另外还使用了JPA规范。默认情况下,该方法本身返回包含前20个结果的页面

我不相信Oracle支持开箱即用的自然排序,所以我有一个存储过程。使用此过程运行查询可以得到所需的结果

select ... from group order by NATURALSORT(group.name) asc
正如您可能期望的那样,我希望使用这个过程,将它包装在包含文本的每个有序列上。同时维护使用分页/页面和规范。到目前为止,我所做的研究为我指出了一个解决方案,其中可能包括

  • 创建和实现自定义规范
  • 或者扩展SimpleParepository以更改排序对象的转换方式
但我似乎没有找到一种方法,允许我使用本机SQL设置顺序。我发现设置顺序的唯一方法是调用
orderBy
并包含
order
对象

一般来说是这样

  • 在使用SpringDataJPA、hibernate和Oracle数据库时,是否有一种全局启用自然排序的方法
  • 如果没有,我如何在仍然能够使用
    Page findAll(Pageable,Specifications)
    方法的情况下,用存储过程包装单个
    order by column

  • 提前谢谢。

    我不知道有这样的功能。但是,您可以将数字存储在单独的列中,然后按该列排序,这将提供更好的排序性能,这是一个额外的好处。

    在深入研究Spring JPA和Hibernate的源代码之后,我设法找到了解决问题的方法。我很确定这不是解决问题的好办法,但这是我唯一能找到的办法

    通过扩展
    SingularAttributePath
    类,我最终实现了查询“orderby”部分的包装器。此类有一个render方法,该方法生成插入到实际查询中的字符串。我的实现如下所示

    1. group one
    2. group two
    10. group ten
    11. group eleven
    
    @Override
    public String render(RenderingContext renderingContext) {
      String render = super.render(renderingContext);
      render = "MYPACKAGE.NSORT(" + render + ")";
      return render;
    }
    
    接下来,我扩展了SimpleParepository类中的订单转换功能。默认情况下,这是通过调用
    QueryUtils.toOrders(排序、根、生成器)
    完成的。但是由于方法调用无法重写,我最终自己调用了
    toOrder
    方法,并根据自己的喜好修改了结果

    这意味着用
    SingularAttributePath
    类的自定义实现替换结果中的所有订单。作为额外的扩展,我扩展了
    Sort
    类,该类由
    Pageable
    类使用,以控制哪些内容被包装,哪些不被包装(称为NaturalOrder)。但我马上就要说了。我的实现与此非常接近(省略了一些检查)

    最后,我替换了
    PageableHandlerMethodArgumentResolver
    使用的
    SortHandlerMethodArgumentResolver
    。这样做的唯一一件事是创建my
    NaturalSort
    类的实例,并将它们传递到可分页对象中,而不是默认的
    Sort

    最后,我可以调用相同的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
    

    我希望这个解决方案能够帮助那些在自然排序和SpringJPA方面有相同或衍生问题的人。如果您有任何问题或改进,请告诉我。

    这不是一个选项,因为名称由用户设置。因此,我对该信息的内容没有影响。有没有办法将本机SQL添加到findAll方法生成的查询中?@RobinHermans因此,输入的文本没有预定义的格式?也就是说,用户可以输入“这是第二组”,并且必须在排序顺序中位于“这是第十组”之前?是的。你在窗口得到的那种命令explorer@RobinHermans对不起,我不知道在这种情况下你能利用什么。