当前位置: 首页 > 知识库问答 >
问题:

Hibernate条件查询-同时按两列排序

楚彦
2023-03-14

我最近在尝试按两个同等重要的列排序一个Hibernate Criteria查询时遇到了这个问题。基本上,我的意思是,如果我有一个表,其中一个列是一个日期(createdOnDate),另一个列是一个日期(modifiedOnDate),我希望比较来自Organization Object的orderBy子句中的所有日期。

为此,我这样尝试:

session.createCriteria(Organization.class).addOrder(Order.desc("modified_date")).addOrder( Order.desc("created_date") ).list();

但是它首先根据modified_date对所有组织进行排序,然后再次使用created_date进行排序。这意味着修改后的记录可能出现在任何createdOn记录之前,即使createdOnDate更早。

共有1个答案

高朝明
2023-03-14

您可以使用sql中的“coalesce()”函数从两个列中取值,

ORDER BY COALESCE( alias_1.modified_date, alias_1.created_date ) ASC;

因此,它意味着如果值存在于“modified_date”列中,则接受排序,如果不存在,则从“created_date”中接受排序。

在COALESCE()函数的hibernate标准中,我认为没有Order Bean,因此您可以扩展和编写自己的实现。

public class CoalesceOrder extends Order {
private String[] properties;

protected CoalesceOrder(boolean ascending, String... properties) {
    super(properties.toString(), ascending);
    this.properties = properties;
}

@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
        throws HibernateException {

    StringBuilder fragment = new StringBuilder();
    StringBuilder exp = new StringBuilder();
    fragment.append("COALESCE(");
    SessionFactoryImplementor factory = criteriaQuery.getFactory();
    for (int j = 0; j < this.properties.length; j++) {
        String propertyName = this.properties[j];
        String[] columns = criteriaQuery.getColumnsUsingProjection(
                criteria, propertyName);
        Type type = criteriaQuery.getTypeUsingProjection(criteria,
                propertyName);
        StringBuilder fragForField = new StringBuilder();
        for (int i = 0; i < columns.length; i++) {
            final StringBuilder expression = new StringBuilder();
            boolean lower = false;
            if (super.isIgnoreCase()) {
                int sqlType = type.sqlTypes(factory)[i];
                lower = sqlType == Types.VARCHAR || sqlType == Types.CHAR
                        || sqlType == Types.LONGVARCHAR;
            }

            if (lower) {
                expression.append(
                        factory.getDialect().getLowercaseFunction())
                        .append('(');
            }
            expression.append(columns[i]);
            if (lower)
                expression.append(')');
            fragForField.append(expression.toString());
            if (i < columns.length - 1)
                fragForField.append(", ");
        }
        exp.append(fragForField.toString());
        if (j < properties.length - 1)
            exp.append(", ");
    }
    exp.append(")");

    fragment.append(factory.getDialect().renderOrderByElement(
            exp.toString(), null, super.isAscending() ? "asc" : "desc",
            factory.getSettings().getDefaultNullPrecedence()));
    return fragment.toString();
}

public static Order asc(String... properties) {
    return new CoalesceOrder(true, properties);
}

public static Order desc(String... properties) {
    return new CoalesceOrder(false, properties);
}
}
criteria.addOrder(CoalesceOrder.desc("modified_date", "created_date"));
 类似资料:
  • 问题内容: 我正在尝试做一个标准查询,该查询返回像常见问题一样的stackoverflow中回答最多的问题。 一个问题包含多个答案。 我试图以标准查询返回按每个问题的答案数排序的最常回答的问题。 有人知道我应该在hibernate标准util中使用什么吗? 问题答案: 这将返回一个Object []列表。每个Object []都将问题的ID作为第一个元素,并将此问题的答案数目作为第二个元素。问题按

  • 我有一个表“Quote”,映射在hibernate中,它有一个由整数id和日期组成的复合键,还有几个附加列。我想编写一个条件查询,它使用DetachedCriteria来获取每个id中日期最长的行。 在sql中,我可能会编写一个查询,比如 在hibernate中,我认为可以像这样为“group by”子查询创建DetachedCriteria(其中Quote是映射表的类,“Qid”是键的复合id类

  • 我被一个简单的问题困住了;如何在ed实体上调用。基本上,我正试图通过JPA标准实现以下目标: 我有以下几点: 如何通过d.name,c.name使用来实现

  • 问题内容: 谁能指出我如何将order by子句作为命名参数传递给HQL? 有效的示例: 无效的示例: 问题答案: 不支持,只能在and 子句中使用输入参数,并且不能为子句使用参数。或者,如果我改写,您不能对列使用参数,只能对值使用。因此,要么: 有尽可能多的命名查询排序顺序 将排序字符串连接到查询字符串 使用条件查询

  • subcompany.hbm.xml 子单位表 branch.java 指定表 我需要帮助编写条件查询使用提供的SQL。

  • 我在代码中使用条件查询。它总是激发 相反,我想忽略查询中的一列(字段),因为该字段以字节形式存储了大量数据。导致性能问题。 有谁能给出一个主意吗? 一些更新 我在查询中添加了一个投影,它创建了一个类似... 现在问题就像..中的未知列“y4_”以及y8_和y5_的相同错误意味着关闭它给出错误的所有内容。 我把它修改成像... 而且奏效了。但是不知道在HQL里面怎么修改?