带有标准别名的 Grails GORM
Grails GORM withCriteria Alias
我已经使用 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");
我查看了休眠生成的原始查询。我注意到那里打印了 'nextServiceIn',没有任何别名作为前缀。
例如'order 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))
}
我已经使用 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");
我查看了休眠生成的原始查询。我注意到那里打印了 'nextServiceIn',没有任何别名作为前缀。
例如'order 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))
}