我的自定义订单,按条件查询/ jpql

时间:2019-04-23 08:23:52

标签: java sql jpql criteria

是否可以通过使用Java中的条件查询或jpql来执行我的自定义订单?在我的表格中,我有一列-数字类型(目前,该列包含诸如123510之类的数字)。我想按251103的顺序对结果进行排序。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyEntity> cq = cb.createQuery(MyEntity.class);
Root<MyEntity> root = cq.from(MyEntity.class);

cq.select(root);
cq.where(cb.equal(root.get("someMyFields"), "myExpectedFieldValue"));
cq.orderBy(cb.asc(root.get("myNumberField"))); // how can I sort result in this order 2, 5, 1, 10, 3?

TypedQuery<MyEntity> query = em.createQuery(cq);
query.setFirstResult(0);
query.setMaxResults(200);

return query.getResultList();

我该怎么办?

2 个答案:

答案 0 :(得分:0)

您必须在CASE子句中使用ORDER BY表达式来实现这种"sort indirection"。在SQL和JPQL中,这将是:

ORDER BY CASE myNumberField 
  WHEN 2  THEN 1
  WHEN 5  THEN 2
  WHEN 1  THEN 3
  WHEN 10 THEN 4
  WHEN 3  THEN 5
          ELSE 6
END

使用标准API,使用CriteriaBuilder.selectCase()

cq.orderBy(
  qb.selectCase(root.get("myNumberField"))
    .when(qb.literal(2), qb.literal(1))
    .when(qb.literal(5), qb.literal(2))
    .when(qb.literal(1), qb.literal(3))
    .when(qb.literal(10), qb.literal(4))
    .when(qb.literal(3), qb.literal(5))
    .otherwise(qb.literal(6))
    .getExpression()
    .asc());

当然,更好的解决方案是在一个单独的表中标准化这些值,您可以将其加入以进行排序:

SELECT *
FROM t
JOIN orderings o ON t.myNumberField = o.myNumberField
ORDER BY o.orderDefinition

答案 1 :(得分:0)

您还可以通过在数据库 bean 中使用特殊字段来对 CriteriaQuery 使用自定义排序:

// this is used for obtaining an arbitrary ordering by statuses
@Formula(value="(CASE status\n" +
        "           WHEN 'DELETED'::text THEN 1\n" +
        "           WHEN 'UPDATED'::text THEN 2\n" +
        "           WHEN 'SUBMITTED'::text THEN 3\n" +
        "           ELSE 10\n" +
        "           END)")
private int statusPriority;

您可以通过 Pagination 对象将 statusPriority 用作常规排序字段。结果查询将包含如下内容:

order by (CASE quotationv0_.status
           WHEN 'DELETED'::text THEN 1
           WHEN 'UPDATED'::text THEN 2
           WHEN 'SUBMITTED'::text THEN 3
           ELSE 10
           END) asc