我们如何在grails标准投影中添加自定义聚合函数?

时间:2016-01-12 08:39:34

标签: hibernate grails groovy gorm

我正在尝试使用标准阻止我的查询。在我的查询中,我有min,max,count和Oracle中位数函数。 如何创建中值函数并在creteria投影部分调用它?

def getTotalResult() {
    def map= [:]
    def result = Freight.createCriteria()
    def freightResults = result.list {
        projections {
            groupProperty "polCode" // 0
            groupProperty "podCode" // 1
            groupProperty "ctnSize" // 2
            groupProperty "carNam"  // 3
            groupProperty "curCode" // 4
            groupProperty "motCode" // 5
            count()
            min('unitValue')
            max('unitValue')
            med('unitValue')        // HOW CREATE THIS CUSTOM FUNCTION 
        }
    }
    freightResults.each {
        map.put(it[6], it)
    }
    return map
}

1 个答案:

答案 0 :(得分:0)

我有同样的问题,我想添加createCriteria mysql的full-text功能,所以我看了RLikeExpression.java并实现了全文,首先我创建了{{ 1}}

Criterion

然后我添加了import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.criterion.CriteriaQuery; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.MatchMode; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.engine.spi.TypedValue; public class MysqlMatchAgainstExpression implements Criterion { private static final long serialVersionUID = -2143299180509579568L; private final String searchColumns; private final String searchValue; public MysqlMatchAgainstExpression(String searchColumns, Object searchValue) { this.searchColumns = searchColumns; this.searchValue = searchValue; } public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { Dialect dialect = criteriaQuery.getFactory().getDialect(); def searchColumnsField = this.searchColumns.replace("(", "").replace(")", "").split(",").collect{ it -> def columns = criteriaQuery.getColumnsUsingProjection(criteria, it.trim()); return columns[0] }.join(", ") return "match (${searchColumnsField}) against (? in boolean mode)" } public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { //return new TypedValue[] { criteriaQuery.getTypedValue(criteria, searchColumns, searchValue.toString().toLowerCase()) }; def property = this.searchColumns.replace("(", "").replace(")", "").split(",").first(); println property return [ criteriaQuery.getTypedValue(criteria, property, searchValue.toString()) ] as TypedValue[]; } @Override public String toString() { return "match ${searchColumns} against ('${searchValue}' in boolean mode)"; } } HibernateCriteriaBuilder fullTextSearch

method

我可以像这样使用它......

void doWithDynamicMethods() {
    grails.orm.HibernateCriteriaBuilder.metaClass.fullTextSearch= {searchColumns, searchValue->
        addToCriteria(new MysqlMatchAgainstExpression(searchColumns, searchValue));
        return this;
    }
}

我知道它本身并没有回答这个问题,而且它不是投影的标准,但我希望在此之后它可以帮助您创建方法User.createCriteria().list{ fullTextSearch "(name, addressLine1, addressLine2)", 'mordor' }.each{it -> println it.name }

好的,我想看看如何做出预测,看起来就像是这样

med

然后添加到public class MedianProjection extends AggregateProjection { public MedianProjection (String propertyName) { super( "MEDIAN", propertyName ); } }

HibernateCriteriaBuilder

让我们越过手指,希望它有效:)

void doWithDynamicMethods() {
    grails.orm.HibernateCriteriaBuilder.metaClass.med= {propertyName->
        def proj = new MedianProjection (calculatePropertyName(propertyName));

        addProjectionToList(proj, alias);

        return this;
    }
}