Spring Data JPA中的排序表达式

4
我有以下实体类,其中objectId是包含字母和数字的字符串。
@Data
@Entity
@Table(name = "CASE_INFO")
public class CaseInfo {
  @Id
  @Column(name = "ID")
  private UUID id;

  @Column(name = "OBJECT_ID")
  private String objectId;
}

我还有以下仓库

@Repository
public interface CaseInfoRepository extends JpaRepository<CaseInfo, UUID>, JpaSpecificationExecutor<CaseInfo> { }

现在,当我使用Specification和Pageable对象执行查询时,可以像这样进行。
Specification<CaseInfo> specification = (Specification<CaseInfo>) (root, query, criteriaBuilder) -> criteriaBuilder.and();
Pageable pageable = PageRequest.of(0, 25, Sort.by("objectId"));
caseInfoRepository.findAll(specification, pageable);

我希望能够根据CaseInfo.objectId进行数字排序,以便在SQL查询中的排序方式看起来类似于:
... order by to_number(OBJECT_ID) ...

如果我做类似于以下的操作

PageRequest.of(0, 25, Sort.by("objectId"))

我希望它可以按照我的使用情况正确排序,而不是字母顺序,因为 "100" 在 "2" 之前。

我在 https://www.baeldung.com/spring-data-jpa-query 上找到了一个使用的例子。

JpaSort.unsafe("LENGTH(name)")

但这似乎行不通,因为如果我这样做

PageRequest.of(0, 25, JpaSort.unsafe("to_number(objectId)"))

它会显示错误信息“没有找到CaseInfo的属性!你想说‘id’吗?”

有人知道如何给Sort对象自定义表达式吗?


Please include actual usage. - Antoniossss
你是什么意思? - griips21
展示你使用某些东西时出现问题的代码,并记得包括那些“原因”。 - Antoniossss
1
我知道这不是你问题的答案,但是把objectId作为Long类型而不是String类型会更简单吗? - Chayne P. S.
是的,可能吧,但我希望使用spring-jpa能有一个简单的解决方案。 - griips21
1
我认为,即使在更高的层面上可以找到某种解决方案,但是数据在数据层中没有索引进行排序。性能将非常糟糕。 - Chayne P. S.
1个回答

4

您可以添加一个公式字段,将字符串值转换为数字,并按照该字段进行排序,或使用默认实现findAll(Pageable pageable)

@Data
@Entity
@Table(name = "CASE_INFO")
public class CaseInfo {
  @Id
  @Column(name = "ID")
  private UUID id;

  @Column(name = "OBJECT_ID")
  private String objectId;

  @Formula(value = "CAST(OBJECT_ID AS NUMERIC(10, 0))")
  private int numObjectId;
}

存储库:

@Repository
public interface CaseInfoRepository extends 
                 JpaRepository<CaseInfo, UUID>, JpaSpecificationExecutor<CaseInfo> {

    // sort by formula field 
    List<CaseInfo> findAllByOrderByNumObjectId(Pageable pageable);
}

在使用@Formula时,有一个技巧是使用CAST函数 -- 当转换为INTINTEGERBIGINT时,这种方法很可能会失败,但是当转换为NUMERIC(10, 0)时可以运行。

NUMERIC的大小也应足够大,以包含转换后字符串中的值,否则可能会发生整数溢出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接