Hibernate 有条件的圣杯

Hibernate 有条件的圣杯,hibernate,grails,gorm,grails-domain-class,Hibernate,Grails,Gorm,Grails Domain Class,我想在orderBy子句的Grails条件中使用NVL函数。我该如何使用?我尝试了多种方法。有人能帮我吗 要转换为Grails条件的SQL查询: 按NVL(字段1、字段2)ASC选择*forom域\表顺序 方法1: Domain.createCriteria().list(max:10,offset:10){ order(field1,'ASC') order(field2,'ASC') } 工作正常,但生成SQL查询时 Select * forom Domain_Table or

我想在orderBy子句的Grails条件中使用NVL函数。我该如何使用?我尝试了多种方法。有人能帮我吗

要转换为Grails条件的SQL查询: 按NVL(字段1、字段2)ASC选择*forom域\表顺序

方法1:

Domain.createCriteria().list(max:10,offset:10){
   order(field1,'ASC')
   order(field2,'ASC')
}
工作正常,但生成SQL查询时

Select * forom Domain_Table order by field1 ASC,field2 ASC
这不符合我的要求

方法2:

 Domain.createCriteria().list(max:10,offset:10){
       order(nvl(field1,field2),'ASC')
    }
错误:Nvl不是域类的属性

方法3:

Domain.createCriteria().list(max:10,offset:10){
   projections{
  addProjectionToList(Projections.sqlProjection("nvl(field1,field2) as description", ['description'] as String[], [Hibernate.STRING] as Type[]), 'description'))
           order('description,'ASC')
        }
问题: 我是根据确切的顺序得到记录的。但是,我再次使用数据库来获取我不想要的域。 还有一个选项,我可以放置我将得到响应的属性(名称、别名)。但是,我需要查询整个域


请帮帮我。您可以使用@Formula作为实体上的人工字段(我们将其命名为
nvl
),然后在排序中使用它

或者您可以使用订单的自定义实现

public class OrderBySqlFormula extends Order {
    private String sqlFormula;

    /**
     * Constructor for Order.
     * @param sqlFormula an SQL formula that will be appended to the resulting SQL query
     */
    protected OrderBySqlFormula(String sqlFormula) {
        super(sqlFormula, true);
        this.sqlFormula = sqlFormula;
    }

    public String toString() {
        return sqlFormula;
    }

    public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        return sqlFormula;
    }

    /**
     * Custom order
     *
     * @param sqlFormula an SQL formula that will be appended to the resulting SQL query
     * @return Order
     */
    public static Order sqlFormula(String sqlFormula) {
        return new OrderBySqlFormula(sqlFormula);
    }
}
并使用
criteria.addOrder(OrderBySqlFormula.sqlFormula(“(a+b)desc”)

从这里


由于您必须使用标准,因此在不修改域类的情况下,您的第三种方法最接近解决方案

您可以将域类
id
添加到投影中,获取所有id,最后调用
domain.getAll()
返回实例。您将需要两个查询,但第二个查询使用主键,因此它将尽可能快地运行

def ids = Domain.createCriteria().list(max:10,offset:10){
   projections{
      property('id')
      sqlProjection("nvl(field1,field2) as description", 'description', Hibernate.STRING)           
   }
   order('description','ASC')
}*.getAt(0) // Only selects the first column: the ID.

def instances = Domain.getAll(ids)

这是一个非常好的方法。你能建议其他的方法吗@Stanislavlha您是否尝试过HQL查询?我不确定它是否处理NVL,但它应该是这样的:
Domain.executeQuery('select d from Domain as d order by NVL(d.field1,d.field2)
。与条件查询投影不同,使用HQL可以投影根实体(Domain)@EmmanuelRosa:我可以使用HQL,也可以执行。但是,我有一个不使用HQL的限制。我只需要使用标准…同意…但是,正如我提到的,它需要一个额外的DB调用,这会让我付出更多的代价?