在我们的域/实体对象中,我们有一个枚举字段,但枚举值作为字符串存储在数据库中
@Column(name = "priority")
@Enumerated(EnumType.STRING)
public Priority getPriority() {
return priority;
}
所以当我们尝试使用 jpa findall 方法按此字段排序时
order by
priority
in 只能按字母顺序排序!然而,我们需要为那里的各个值分配顺序。
public enum Priority {
Critical,
Major,
Minor,
Informational
}
有没有办法在这里定义jpa在排序/排序时遵循的顺序?
我知道纯sql是可能的
order by (case priority when 'Critical' then 0 when 'Major' then 1 when 'Minor' then 2 else 3 end);
似乎应该有办法用 jpa 来做到这一点
JPQL 也支持
CASE
。使用 Hibernate 5.6.x 作为持久性提供程序,我能够成功运行以下查询:
// define the mapping from priority name to value in the SELECT clause
Query q = em.createQuery("SELECT a, CASE " +
"WHEN a.priority='Critical' THEN 4 " +
"WHEN a.priority='Major' THEN 3 " +
"WHEN a.priority='Minor' THEN 2 " +
"ELSE 1 END AS pri " +
"FROM AnEntity a ORDER BY pri");
// remember this returns an Object[]!
@SuppressWarnings("unchecked")
List<Object[]> results = q.getResultList();
// the results are in the correct order, the first element is the AnEntity
我很惊讶地发现这个案例也适用于
ORDER BY
子句 - 但这可能是 Hibernate 特定的扩展(见下文):
Query q = em.createQuery("SELECT a FROM AnEntity a ORDER BY " +
"CASE WHEN a.priority='Critical' THEN 4 " +
"WHEN a.priority='Major' THEN 3 " +
"WHEN a.priority='Minor' THEN 2 " +
"ELSE 1 END");
JPA 2.1 规范 ch.4.6.17.4 将 Case 表达式定义为标量表达式。在ch.4.6.17“标量表达式”中,它说:
标量表达式可以用在查询的 SELECT 子句以及 WHERE 和 HAVING 子句中。
因此在
ORDER BY
中使用它可能是 Hibernate 特定的,但我会尝试一下,然后回到第一个选项。