Hibernate 用于grails标准投影的Mysql group_concat替代方案
假设我有两个简单的域类:Hibernate 用于grails标准投影的Mysql group_concat替代方案,hibernate,grails,criteria,group-concat,Hibernate,Grails,Criteria,Group Concat,假设我有两个简单的域类: class A { String name static hasMany = [bs: B] } class B { String title } 现在,我想生成一个如下结构的项目列表: // id of A instance, name of A instance, comma separated list of Bs titles associated to A istance 1, "A1", "B1, B2" 2, "A2", "B
class A {
String name
static hasMany = [bs: B]
}
class B {
String title
}
现在,我想生成一个如下结构的项目列表:
// id of A instance, name of A instance, comma separated list of Bs titles associated to A istance
1, "A1", "B1, B2"
2, "A2", "B2, B5"
...
这是我获得的标准:
def list = A.withCriteria {
createAlias 'bs', 'bs', CriteriaSpecification.LEFT_JOIN
projections {
property 'id'
property 'name'
property 'bs.title' // this is the interesting line
}
}
这显然只检索与我的A实例相关的B元素的第一个标题。像这样:
1, "A1", "B1"
2, "A2", "B2"
...
现在,现实生活中的场景有点复杂,我已经简化了,这就是:我如何才能在bs标题中获得与mysql group_concat相同的效果
我试图用一个标准来实现这一点,但如果不可能,我很乐意讨论另一个解决方案。它与您的排序实现相同
def list = A.withCriteria {
createAlias 'bs', 'bs', CriteriaSpecification.LEFT_JOIN
projections {
property 'id'
property 'name'
property 'bs.title' // this is the interesting line
}
order "id", "asc"
order "bs.title", "asc"
}
//Bootstrap
def a = new A(name: "TestA1").save()
def a1 = new A(name: "TestA2").save()
def b1 = new B(title: "TitleB1")
def b2 = new B(title: "TitleB2")
def b3 = new B(title: "TitleB3")
def b4 = new B(title: "TitleB4")
def b5 = new B(title: "TitleB5")
[b1, b2, b3].each{a.addToBs(it)}
[b2, b4, b5].each{a1.addToBs(it)}
[a, a1]*.save(flush: true, failOnError: true)
您可以分组以获得每个组合的键值对
//This can be optimized
list.groupBy({[it[0], it[1]]})
//Would give
[[1, TestA1]:[[1, TestA1, TitleB1], [1, TestA1, TitleB2], [1, TestA1, TitleB3]],
[2, TestA2]:[[2, TestA2, TitleB2], [2, TestA2, TitleB4], [2, TestA2, TitleB5]]
]
这是另一种方式
class A {
String name
static hasMany = [bs: B]
def childrenString() {
B.findAllByParent(this).collect{ it.title }.join(',')
}
}
class B {
static belongsTo = A
A parent
String title
static constraints = {
}
}
A.list().each { it ->
println "${it.name}, ${it.childrenString()}"
}
我忘了提到,我正在寻找一种不使用mysql group_concat函数的方法。我能够获得所有关联,使用内存数据库作为列表。一些额外的收集工具会得到你想要的<代码>[[1,测试1,标题1],[1,测试1,标题2],[1,测试1,标题3],[2,测试2,标题2],[2,测试2,标题4],[2,测试2,标题5]。这种行为是MySql特有的吗?你能在内存数据库中的H2中测试这些信息吗?@dmahapatro你如何检索这些信息?用一个单独的查询?如何合并这两个结果?请随意发布答案。这是一个可能的解决方案,但我不太喜欢在域类中保留一些表示逻辑。您可以将其放置在服务中并调用itThanks,但输出的格式不是我需要的格式。此外,这些并不是我从A中需要的唯一信息,因为我说过标准要复杂得多,我的示例非常简单,您的解决方案创建的数据结构要比需要的复杂得多。