我需要在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
答案 0 :(得分:0)
尝试这样的事情:
Yourdomain.withSession{ session ->
session.createSQLQuery(yourQueryWithGroup_concat).setLong(yourParameterName,yourParameterValue).list()
}