2013-06-26 2 views
0

의 나는 두 가지 간단한 도메인 클래스가 있다고 가정 해 봅시다 : 지금, 나는이 같은 구조 항목의 목록을 생성 할의 MySQL의 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", "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 
    } 
} 

을이 분명히 B의 elemen의 첫 번째 제목을 검색합니다 기준은 그것을 얻기 위해 내 A 인스턴스와 관련된. 이처럼 : 나는 학사 타이틀 MySQL의 GROUP_CONCAT 동일한 효과를 얻을 수있는 방법 :

1, "A1", "B1" 
2, "A2", "B2" 
... 

이제, 실제 시나리오는 조금 더 복잡, 내가있는 지점에 도착하기 위해 단순화했습니다입니까?

나는 하나의 기준으로이를 수행하려고 노력하고 있지만 가능한 경우 다른 해결책을 논의하게되어 기쁩니다.

+0

입니다. – lucke84

+0

인 메모리 db를 사용하여 모든 연관을 목록으로 얻을 수 있습니다. 추가 수집 유틸리티를 사용하면 원하는 것을 얻을 수 있습니다. 1, TestA1, TitleB2], [1, TestA1, TitleB3], [2, TestA2, TitleB2], [2, TestA2, TitleB4], [2, TestA2, TitleB5]] [ '. 이 동작은 MySql에만 해당합니까? H2 in-memory db에서 같은 것을 테스트 할 수 있습니까? – dmahapatro

+0

@dmahapatro 어떻게 정보를 검색하나요? 별도의 쿼리를 사용합니까? 두 결과를 어떻게 병합합니까? 자유롭게 답변을 게시하십시오. – lucke84

답변

0

주문과 동일한 구현입니다.

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) 

각 조합에 대해 키 값 쌍을 얻기 위해 groupBy를 사용할 수 있습니다.

//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]] 
] 
+0

감사합니다. 출력이 필요한 형식이 아닙니다. 게다가 이러한 것들이 A에서 필요로하는 유일한 정보는 아닙니다. 기준이 훨씬 복잡하고 예제가 매우 간단하며 솔루션이 훨씬 복잡한 데이터 구조를 생성한다고 말했기 때문입니다. – lucke84

0

이 내가 MySQL의 GROUP_CONCAT 기능을 사용하지하는 방법을 찾고, 내가 얘기를 깜빡 했네요 다른 방법

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()}" 
} 
+0

이것은 가능한 해결책이지만 도메인 클래스 내에 일부 표현 논리를 유지하는 아이디어가 마음에 들지 않습니다. – lucke84

+0

서비스에 배치하고 호출 할 수 있습니다 – JavaDev