我已使用grails设置了一个gorm标准查询。有一些sqlProjections包括在内。现在我需要通过这个sqlProjections订购。
def serviceList = Service.withCriteria {
projections {
property('id', 'id')
property('lastServiceMileage', 'lastServiceMileage')
property('nextServiceMileage', 'nextServiceMileage')
sqlProjection('(SELECT MAX(e.mileage) FROM tbl_maxmileage AS e WHERE e.v_id = {alias}.v_id) AS mileage', ['mileage'], [INTEGER])
sqlProjection('(ABS((SELECT mileage) - {alias}.last_service_mileage) / ({alias}.next_service_mileage - {alias}.last_service_mileage)) * 100 AS nextServiceInPercent', ['nextServiceInPercent'], [INTEGER])
sqlProjection('{alias}.next_service_mileage - (SELECT mileage) AS nextServiceIn', ['nextServiceIn'], [INTEGER])
}
if (params.sort && params.order) {
order(params.sort, params.order)
}
firstResult(params.int('offset'))
maxResults(params.int('max'))
setResultTransformer(Transformers.aliasToBean(Service.class))
}
Hibernate失败并打印出来,例如。如果params.sort = nextServiceIn
,则找不到“nextServiceIn”我认为这是因为我没有在'nextServiceIn'前面写一个别名。
现在我需要知道如何使用'withCriteria'
定义标准根别名使用会话对象可以使用
完成 hibernateSession.createCriteria(Service.class, "s");
答案 0 :(得分:1)
我查看了hibernate生成的原始查询。我注意到'nextServiceIn'在那里打印时没有任何别名作为前缀。
例如'by nextServiceIn asc'...
现在解决方案是扩展org.hibernate.criterion.Order并实现基本排序而不进行任何查找。
import org.hibernate.criterion.Order
import org.hibernate.criterion.CriteriaQuery
import org.hibernate.Criteria
import org.hibernate.HibernateException
/**
* Created with IntelliJ IDEA.
* User: pheinrich
* Date: 18.01.16
* Time: 16:33
* To change this template use File | Settings | File Templates.
*/
public class OrderBySql extends Order {
private String sqlOrderString;
/**
* Constructor for Order.
* @param sqlOrderString an SQL order that will be appended to the resulting SQL query
*/
protected OrderBySql(String sqlOrderString) {
super(sqlOrderString, true);
this.sqlOrderString = sqlOrderString;
}
public String toString() {
return sqlOrderString;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return sqlOrderString;
}
/**
* Custom order
*
* @param sqlProperty an SQL property that will be appended to the resulting SQL query
* @param sqlOrder an SQL order that will be appended to the resulting SQL query
* @return Order
*/
public static Order sqlOrder(String sqlProperty, String sqlOrder) {
return new OrderBySql(sqlProperty + " " + sqlOrder);
}
}
并在GORM标准中使用
def serviceList = Service.withCriteria {
projections {
property('id', 'id')
property('lastServiceMileage', 'lastServiceMileage')
property('nextServiceMileage', 'nextServiceMileage')
sqlProjection('(SELECT MAX(e.mileage) FROM tbl_maxmileage AS e WHERE e.v_id = {alias}.v_id) AS mileage', ['mileage'], [INTEGER])
sqlProjection('(ABS((SELECT mileage) - {alias}.last_service_mileage) / ({alias}.next_service_mileage - {alias}.last_service_mileage)) * 100 AS nextServiceInPercent', ['nextServiceInPercent'], [INTEGER])
sqlProjection('{alias}.next_service_mileage - (SELECT mileage) AS nextServiceIn', ['nextServiceIn'], [INTEGER])
}
if (params.sort && params.order) {
// special handling for sqlProjection alias
if (params.sort == "nextServiceIn") {
order(OrderBySql.sqlOrder(params.sort, params.order))
} else {
order(params.sort, params.order)
}
}
firstResult(params.int('offset'))
maxResults(params.int('max'))
setResultTransformer(Transformers.aliasToBean(Service.class))
}