2014-04-24 32 views
6

我有兩個域搜索記錄在最新的記錄基地在的hasMany關係

class DomainA { 
    String name 
    Date dateCreated 
    Date lastUpdated 

    static transients = ['email'] 

    static hasMany = [domainBs: DomainB] 

    public String getEmail() { 
     DomainB.mostRecentRecord(this).get()?.email 
    } 
} 

class DomainB { 
    String email 
    Date dateCreated 
    Date lastUpdated 

    static belongsTo = [domainA: DomainA] 

    static namedQueries = { 
     mostRecentRecord { domainA -> 
      eq 'domainA', domainA 
      order('dateCreated', 'desc') 
      maxResults(1) 
     } 
    } 
} 

我的要求是讓所有DomainA中的名字的名單與「M」開頭,最新的domainBs記錄在其電子郵件屬性中包含gmail。

我試過createCriteriahql但沒有得到想要的結果,可能是我做錯了什麼。

以下是我當前的代碼

List<DomainA> listA = DomainA.findAllByNameIlike("M%") 
List<DomainB> listB = [] 
listA.each { entity -> 
    DomainB domainB = DomainB.mostRecentRecord(entity).get() 
    if (domainB && (domainB.email.contains('gmail'))) { 
     listB.add(domainB) 
    } 
} 

,但它並沒有允許分頁和排序。

有人可以有任何想法獲得名稱以「M」開頭的所有DomainA列表,並且最新的domainBs在其電子郵件屬性中使用createCriteriahql或任何其他方式包含gmail。

回答

4

由於您正在查找最新的電子郵件,因此您需要查看secondDomain上的max dateCreated。你可以使用HQL編寫它並使用executeQuery傳遞你的分頁參數。只要確保在dateCreated上有索引。

FirstDomain.executeQuery("select fd from FirstDomain fd,SecondDomain sd where \ 
     sd.firstDomain.id=fd.id and fd.name like :name and sd.email like :email \ 
     and sd.dateCreated = (select max(sd2.dateCreated) from SecondDomain sd2 \ 
      where sd2.firstDomain.id = fd.id))", 
[email:'%gmail%',name:'M%'], [max: 10, offset: 0]) 

sample code:剛打firstDomainController

 def fd 
     // most recent email is gmail 
     fd = new FirstDomain(name:"Mtest") 
     fd.addToSecondDomain(new SecondDomain(email:'yahoo.com')) 
     fd.addToSecondDomain(new SecondDomain(email:'gmail.com')) 
     fd.save(flush:true) 

     // most recent is yahoo 
     fd = new FirstDomain(name:"MMtest") 
     fd.addToSecondDomain(new SecondDomain(email:'gmail.com')) 
     fd.addToSecondDomain(new SecondDomain(email:'yahoo.com')) 
     fd.save(flush:true) 

     // will return "Mtest" 
     FirstDomain.executeQuery("select fd from FirstDomain fd,SecondDomain sd where sd.firstDomain.id=fd.id and fd.name like :name and sd.email like :email and sd.dateCreated = (select max(sd2.dateCreated) from SecondDomain sd2 where sd2.firstDomain.id = fd.id))",[email:'%gmail%',name:'M%']) 
+0

此查詢每次都會給我一個空列表。 – user1690588

+0

你有滿足要求的數據嗎?查詢區分大小寫。我非常使用你的域名並建立一些樣本數據並進行測試。我會在今晚檢查代碼給github。 – Alidad

+0

我創建了DomainA實例,名爲'Manish'和DomainB實例,電子郵件爲'test @ gmail.com',查詢給了我一個空列表。等待存儲庫。謝謝 – user1690588

1

在Grails的2.4,你應該能夠使用新的相關子查詢功能,做這樣的事情:

DomainA.where { 
    name like 'M%' && exists DomainB.where { 
     id == max(id).of { email like '%gmail%' } 
    } 
} 

不幸的是,我無法在2.4中測試我們的應用程序,因此我無法確認這是否可行。

+0

我正在使用grails 2.3.5,您的查詢給我錯誤,我使用http://grails.org/doc/2.3.7/guide/GORM.html#whereQueries文檔更正了此錯誤。你的查詢給我不正確的結果。它包括DomainA實例,其最新的DomainB是gmail,但在舊記錄中有一個gamil。 – user1690588