在休眠条件中使用mysql“按大小写”

Posted

技术标签:

【中文标题】在休眠条件中使用mysql“按大小写”【英文标题】:using mysql "order by case" in hibernate criteria 【发布时间】:2014-07-24 20:18:46 【问题描述】:

我使用的是 Hibernate 4.3.1 final,mysql 5.5,我想在一些连接实体上使用“按大小写”顺序逻辑。

我希望实现的纯 sql 表示形式如下所示:

select adv.id, adv.published_date 
from advert as adv 
  join account as act on act.id = adv.act_id
  join account_status as aas on aas.id = act.current_aas_id
order by case aas.status
when 'pending' THEN 1
when 'approved' THEN 1
else 2
end, adv.published_date;

这会将待处理和已批准帐户的广告排在停用帐户之前。

我已经设法使用休眠条件执行所有选择查询,但我不确定如何使用该 api 指定按大小写语句的顺序。

我找到了这篇文章:

http://blog.tremend.ro/2008/06/10/how-to-order-by-a-custom-sql-formulaexpression-when-using-hibernate-criteria-api/

但我需要按大小写顺序引用连接的实体类,我不知道该怎么做。

非常感谢任何帮助或建议。

【问题讨论】:

【参考方案1】:

我想我找到了解决办法。

最后我创建了自己的 Order 子类并覆盖了 public String toSqlString(Criteria,CriteriaQuery) 方法:

@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
    final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, getPropertyName() );
    final StringBuilder fragment = new StringBuilder();
    fragment.append(" case ").append(columns[0]);
    fragment.append(" when 'pending' then 1 ");
    fragment.append(" when 'approved' then 1 ");
    fragment.append(" else 2 end");
    return fragment.toString();

重要的调用(我在 order 类的原始实现中找到)是

criteriaQuery.getColumnsUsingProjection(criteria, getPropertyName());

这让我可以使用 case 语句访问我想要订购的列的别名。

如果其他人正在查看此内容,如果您正在对不在根对象上的属性进行排序,请确保您在条件连接中使用别名,然后在自定义订单中正确引用这些别名实例化时的 propertyName。

【讨论】:

【参考方案2】:

除了https://***.com/a/24077763/258559 值得一提的是,现在您正在像这样添加 Order 子类

criteria.addOrder(new CustomOrder());

而不是

criteria.addOrder(CustomOrder.desc(fieldName));

因为 desc/asc 是静态方法,仍然会创建 Order 实例而不是您的 CustomOrder

【讨论】:

以上是关于在休眠条件中使用mysql“按大小写”的主要内容,如果未能解决你的问题,请参考以下文章

mac转发Mac系统升级后,按大小写键没反应了,切换大小写的灯不亮了

sql按大小写排序

在一对多映射中使用休眠条件(以行表列作为搜索条件之一的搜索标题表)

休眠查询语言或使用条件?

休眠条件中日期的限制

休眠条件:在没有映射关联的情况下加入表