Grails GORM withCriteria Alias

时间:2016-01-18 14:37:43

标签: hibernate grails gorm

我已使用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");

1 个答案:

答案 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))

}