【发布时间】:2013-08-19 14:21:40
【问题描述】:
我需要在 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,因为它是特定于数据库的。我可以将我的项目与 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:“点击”{originalText=clicks} .堆栈跟踪如下: 消息:节点没有数据类型:org.hibernate.hql.ast.tree.MethodNode -[METHOD_CALL] 方法节点:'(' +-[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:“点击”{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 中的任何其他 db 特定函数)。我正在使用 grails 2.0.4
【问题讨论】:
标签: mysql hibernate grails grails-orm grails-2.0