如何将String上的PageRequest排序为数值

时间:2016-11-09 13:30:17

标签: java spring spring-data-jpa

我目前有一个系统,可以对数据库中的记录进行过滤和排序,并将它们作为分页对象返回。其中一条线是这样的:

final PageRequest request = new PageRequest(this.pagingSettings.getPageNumber(),
            this.pagingSettings.getPageSize(), sortDirection, sortedBy);

这是正常的,但现在我遇到以下情况。我试图对门牌号码进行排序,这是我的Postgres数据库中的varchar。例如,我们有1个,12个,111个,1004个,但也有1A或36个BASEMENT。对这些(字符)值进行排序时,这些值将排序:1,1004,111,12,1A,......

所以,sortedBy现在是一个String,在本例中是houseNumber。我发现在Postgres中使用ORDER BY参数... ORDER BY NULLIF(regexp_replace(container_number, E'\\D', '', 'g'), '')::int";,排序就像我想要的那样:1,1A,12,111,......

但是,仅将sortedBy字符串更改为sortedBy = "NULLIF(regexp_replace(container_number, E'\\D', '', 'g'), '')::int";似乎不起作用。

是否有人建议如何在不更改数据库的情况下对PageRequest数字中的字符值进行排序?

3 个答案:

答案 0 :(得分:2)

所以基本上你需要做两件事:

  1. 实施自定义比较器,
  2. 注释实体类。
  3. Ad.1。

    public class HouseComparator implements Comparator<House> {
        @Override
        public int compare(House h1, House h2) {
    
            String s1 = h1.getHouseNumber().split("[^0-9]")[0];
            String s2 = h2.getHouseNumber().split("[^0-9]")[0];
    
            return s1.compareTo(s2);
        }
    }
    

    您需要更好地处理案件。上面的比较器说,当h1以较小的数字开头时h2小于12A,反之亦然。对于此比较器,12B等于@SortComparator(HouseComparator.class) List<House> findByHouseNumber(Pageable pageable); ,但这取决于您。

    Ad.2。

    var optionalNum : Int? = 5
    let num1 = optionalNum
    print("num1 is \(num1)")
    
    if let num2 = optionalNum {
        print("num2 is \(optionalNum)")
        print("num2 is \(num2)")
    } else {
        print("optionalNum does not hold a value")
    
    }
    

答案 1 :(得分:2)

我认为您可以尝试允许函数调用的Spring Data JpaSort类。

documentation中所述,您将拥有类似的内容:

@Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);

repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)"));

您也可以将它与Pageable对象一起使用。

答案 2 :(得分:1)

假定您拥有一个实体,并提出了String,并且您想使用jpa Pageable对它进行排序,类似于Long

因此,您需要执行以下操作:(请记住,这仅适用于Oracle数据库)

  1. 在您的实体中添加Long类型的新文件
  2. 对于新提交的文件,在getter方法中使用@Formula并唤起to_number()
@Entity
public class testEntity{
         private String oldField;  //Getter and Setter

         private Long newField; //Setter

         @Formula(value = "to_number(oldField)")
         public Long getNewField() {
                return newField;
         } 
 }
  1. 在您的服务中找到已排序的文件,并将其更改为newfiled
 if (Objects.nonNull(pagingRequest.getSort()) && pagingRequest.getSort().getFieldName().equals("oldField")) {
            pagingRequest.getSort().setFieldName("newField");
 }