Java API中计算列名的ORDER BY准则(按别名)

Java API中计算列名的ORDER BY准则(按别名),java,hibernate,jpa-2.0,criteria-api,criteriaquery,Java,Hibernate,Jpa 2.0,Criteria Api,Criteriaquery,有一种情况,我的java代码是符号查询- SELECT CUSTOMER_ID, CUSTOMER_NAME, CASE WHEN COUNT (DISTINCT CARD_ID) > 1 THEN 'MULTIPLE' ELSE MAX(CARD_NUM) END AS CARD_NUM FROM CUSTOMER LEFT JOIN CARD ON CARD.CU

有一种情况,我的java代码是符号查询-

  SELECT CUSTOMER_ID,
         CUSTOMER_NAME,
         CASE
             WHEN COUNT (DISTINCT CARD_ID) > 1 THEN 'MULTIPLE'
             ELSE MAX(CARD_NUM)
         END    AS CARD_NUM
    FROM CUSTOMER LEFT JOIN CARD ON CARD.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
GROUP BY CUSTOMER_ID, CUSTOMER_NAME
详细信息的Java代码-

CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Tuple> query = cb.createQuery(Tuple.class);
final Root<Customer> root = query.from(Customer.class);
Expression<Object> caseSelect = cb.selectCase()
        .when(cb.greaterThan(cb.countDistinct(join.get(Card_.cardId)), 1L), "MULTIPLE")
        .otherwise(cb.greatest(Card_.get(Card_.cardNum)));
caseSelect.alias("card_num");
selects.add(caseSelect);
query.multiselect(selects).distinct(true);
query.groupBy(exprs);
query.orderBy(cb.asc(caseSelect));
CriteriaBuilder cb=em.getCriteriaBuilder();
最终的CriteriaQuery=cb.createQuery(Tuple.class);
最终根=query.from(Customer.class);
表达式caseSelect=cb.selectCase()
.when(cb.greaterThan(cb.countDistinct(join.get(Card_u.cardd)),1L,“多个”)
。否则(cb.grest(Card_u.get(Card_u.cardNum));
caseSelect.alias(“卡片编号”);
选择。添加(caseSelect);
query.multiselect(selects).distinct(true);
query.groupBy(exprs);
query.orderBy(cb.asc(caseSelect));
现在,如何在API中按条件进行排序

  • 如果我执行orderby root.CARD_NUM,则该属性在root中不存在。-引发异常
  • 如果我按caseSelect表达式本身排序,它将抛出一个错误 说明卡片ID不在查询的选定部分中
  • 我不能在select表达式中使用card\ num/card\ id,这不适合查询
  • 有没有办法直接用别名订购?我了解了顺序是表达式类型,以及如何从字符串名称获取表达式。我想你可以在冬眠状态下这样做。是否可以在CriteriaAPI中使用hibernate orderby?猜一个愚蠢的问题


    感谢您的帮助。

    使用JPA Criteria API,这似乎是不可能的,您将不得不回退到使用JPQL/HQL来代替。

    这是不可能的,只是感觉JPA错过了一个案例。 虽然如果使用HibernateAPI是可能的。但是,我的解决办法是-

  • 创建了一个包含大小写表达式的视图
  • 将视图与我的实体连接(您不能进行连接,只能再进行一次连接 query.from(View.class))
  • 在其中添加视图和实体的ID

  • 现在,在order by中,您可以按View.column_name提及列名。

    使用Criteria API,您需要按
    caseSelect
    表达式进行排序。我尝试了一下,它在Hibernate 5.4中运行良好。你使用哪个版本?

    我也遇到了类似的情况

    query.multiselect(root, computedColumn);
    query.orderBy(new Order[]{filterDTO.getSortAsc() ? cb.asc(cb.literal(2)) : cb.desc(cb.literal(2))});
    
    我的case computedColumn是子查询…我没有设法通过列别名使其工作,但它似乎通过tuple中返回的列索引工作,因此我猜在您的代码中,它应该通过索引1工作

    query.orderBy(cb.asc(cb.literal(1)));