JPA Hibernate按字母数字字段排序

时间:2018-04-05 12:33:44

标签: java hibernate jpa alphanumeric

我正在使用 Jpa / Hibernate Spring Boot 应用

中访问 MariaDB

我很想通过字母数字字段对数据进行排序,这些字段包含可能以一个字母结尾的数字(模式\d+[a-z]?

e.g。

  • 10
  • 104
  • 20A
  • 100B

我需要他们像这样订购

  • 10
  • 20A
  • 100B
  • 104

我使用 Criteria Api 来构建我自己的查询,因为我还必须进行一些复杂的过滤。

@Transactional(readOnly = true)
public class EntryRepositoryImpl implements EntryRepositoryCustom {

  @PersistenceContext
  private EntityManager entityManager;

  @Override
  public Page<Entry> get(MultiValueMap<String, String> parameters, Pageable pageable) {

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

    //  count total number of filterd entries
    Long totalResultCount = getResultCount(parameters, criteriaBuilder);

    // build query to get filterd entries
    CriteriaQuery<Entry> selectQuery = criteriaBuilder.createQuery(Entry.class);
    Root<Entry> getRoot = selectQuery.from(Entry.class);
    CriteriaQuery<Entry> select = selectQuery.select(getRoot);

    addFilters(parameters, criteriaBuilder, getRoot, select);

    // add sorting
    List<javax.persistence.criteria.Order> sortOrders = JpaUtils.translateSorting(pageable,
        getRoot);
    select.orderBy(sortOrders);

    //  get one page of filterd entries
    List<Entry> results = getPageResults(pageable, select);
    return new PageImpl<>(results, pageable, totalResultCount);
  }

  /**
   * Translate spring to jpa sorting.
   */
  public static List<javax.persistence.criteria.Order> translateSorting(Pageable pageable,
      Root<Entry> root) {
    List<Sort.Order> orders = new ArrayList<>();
    if (pageable.getSort() != null) {
      pageable.getSort().iterator().forEachRemaining(orders::add);
    }

    return orders.stream().
        map(order -> {
          String[] parts = order.getProperty().split("\\.");
          String field = parts[0];
          Path path = parts.length == 2 ? root.join(field).get(parts[1]) : root.get(field);
          return new OrderImpl(path, order.isAscending());
        })
        .collect(Collectors.toList());
  }

我已经有了一个自定义比较器,但似乎没有办法翻译它,所以DB可以使用它。

到目前为止,我找到了以下解决方案/想法

  • 使用@SortComparator,但我的用例不可行,因为排序必须在数据库中进行,因为有超过500k的复杂行。
  • sql base solution但不知道如何将其翻译成Criteria Api。
  • 在查看CriteriaBuilderjavadoc)的函数后,我想到将值拆分为数字和字符串部分并应用于订单但是没有用正则表达式拆分的函数

修改

现在,我确实将字段拆分为2并使用两种排序表达式。

0 个答案:

没有答案