Hibernate 有条件的圣杯
我想在orderBy子句的Grails条件中使用NVL函数。我该如何使用?我尝试了多种方法。有人能帮我吗 要转换为Grails条件的SQL查询: 按NVL(字段1、字段2)ASC选择*forom域\表顺序 方法1: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
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调用,这会让我付出更多的代价?