【问题标题】:Sorting expression in spring data JPAspring数据JPA中的排序表达式
【发布时间】:2020-09-17 13:56:25
【问题描述】:

我有以下实体类,其中 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<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 看起来像这样

... 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' 吗?”

有人知道给排序对象自定义表达式的方法吗?

【问题讨论】:

  • 请注明实际使用情况。
  • 你这是什么意思?
  • 显示您正在使用某些东西的代码,但由于某些原因它无法正常工作。记住也要包括那些“原因”.....
  • 我知道这不是您问题的答案,但是将 objectId 设为 Long 而不是 String 更简单吗?
  • 我相信,即使您可以在更高层找到某种解决方案,但数据并没有被索引以在数据层进行排序。表现会很糟糕。

标签: java spring-data-jpa


【解决方案1】:

您可以添加一个公式字段,将字符串值转换为数字值,然后按此字段排序或使用默认实现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);
}

有一个trick with using CAST function in @Formula -- 转换为INTINTEGERBIGINT 时很可能会失败,但转换为NUMERIC(10, 0) 时它可以工作。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多