如何在Grails中使用带有Gorm的GROUP_CONCAT

时间:2013-08-19 14:21:40

标签: mysql hibernate grails gorm grails-2.0

我需要在Grails中使用GROUP_CONCAT聚合函数,最好是来自HQL,但也可以使用标准。

我有这个问题:

ClickTracking.executeQuery("SELECT pageId, containerId, GROUP_CONCAT(clicks) as click" +
                                            "FROM  ClickTracking " +
                                            "WHERE pageId =  ? " +
                                            "GROUP BY containerId ", [pageId])

这不起作用,因为HQL不了解GROUP_CONCAT,因为它是特定于DB的。我可以将我的项目与MySQL绑定,所以我尝试在BootStrap.groovy中添加它:

Configuration conf = grailsApplication.getMainContext().getBean("&sessionFactory").configuration;
conf.addSqlFunction("GROUP_CONCAT", new StandardSQLFunction("GROUP_CONCAT", new StringType()));

没有运气。

然后我尝试将方言子类化并使用它:

import org.hibernate.dialect.MySQL5InnoDBDialect
import org.hibernate.dialect.function.StandardSQLFunction
import org.hibernate.Hibernate

class ExtendedMySqlDialect extends MySQL5InnoDBDialect {

public ExtendedMySqlDialect() {
    super();
    registerFunction("GROUP_CONCAT", new StandardSQLFunction("GROUP_CONCAT", Hibernate.STRING));

}

}

和DataSource.groovy

dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
dialect = "ExtendedMySqlDialect"
logSql = true

}

仍然没有运气。我明白了:

No data type for node: org.hibernate.hql.ast.tree.MethodNode 

- [METHOD_CALL] MethodNode:'('     + - [METHOD_NAME] IdentNode:'GROUP_CONCAT'{originalText = GROUP_CONCAT}      - [EXPR_LIST] SqlNode:'exprList'         - [DOT] DotNode:'clicktrack0_.clicks'{propertyName = clicks,dereferenceType = ALL,propertyPath = clicks,path = {synthetic-alias} .clicks,tableAlias = clicktrack0_,className = com.ui.gorm.ClickTracking,classAlias =空值}           + - [IDENT] IdentNode:'{synthetic-alias}'{originalText = {synthetic-alias}}            - [IDENT] IdentNode:'clicks'{originalText = clicks} 。 Stacktrace如下: 消息:节点没有数据类型:org.hibernate.hql.ast.tree.MethodNode   - [METHOD_CALL] MethodNode:'('     + - [METHOD_NAME] IdentNode:'GROUP_CONCAT'{originalText = GROUP_CONCAT}      - [EXPR_LIST] SqlNode:'exprList'         - [DOT] DotNode:'clicktrack0_.clicks'{propertyName = clicks,dereferenceType = ALL,propertyPath = clicks,path = {synthetic-alias} .clicks,tableAlias = clicktrack0_,className = com.ui.gorm.ClickTracking,classAlias =空值}           + - [IDENT] IdentNode:'{synthetic-alias}'{originalText = {synthetic-alias}}            - [IDENT] IdentNode:'clicks'{originalText = clicks}

Line | Method

- >> 156 | org.hibernate.hql.ast.tree.SelectClause中的initializeExplicitSelectClause

如果我设置了一个断点,我查看了grailsApplication.getMainContext()。getBean(“& sessionFactory”)。configuration我可以找到一个名为sqlFuncions的属性,并且GROUP_COCNAT就在那里。

我做了一些调试,最后我在这段代码中使用了SelectExpressionList.java:

public SelectExpression[] collectSelectExpressions() {
    // Get the first child to be considered.  Sub-classes may do this differently in order to skip nodes that
    // are not select expressions (e.g. DISTINCT).
    AST firstChild = getFirstSelectExpression();
    AST parent = this;
    ArrayList list = new ArrayList( parent.getNumberOfChildren() );
    for ( AST n = firstChild; n != null; n = n.getNextSibling() ) {
        if ( n instanceof SelectExpression ) {
            list.add( n );
        }
        else {
            throw new IllegalStateException( "Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" ) );
        }
    }
    return ( SelectExpression[] ) list.toArray( new SelectExpression[list.size()] );
}

似乎n = n.getNextSibbling()在某种程度上搞乱了group_concat,但这很奇怪,因为那是来自antlr包。

无论如何,我被困住了,我很好奇如何使用group_concat(或gorm中的grails中的任何其他数据库特定函数)。我正在使用grails 2.0.4

1 个答案:

答案 0 :(得分:0)

尝试这样的事情:

Yourdomain.withSession{ session ->  
   session.createSQLQuery(yourQueryWithGroup_concat).setLong(yourParameterName,yourParameterValue).list()  
}