2014-04-24 19 views
6

mam dwie domenySzukaj rekordy bazy na najnowszej płycie w związku hasMany

class DomainA { 
    String name 
    Date dateCreated 
    Date lastUpdated 

    static transients = ['email'] 

    static hasMany = [domainBs: DomainB] 

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

i

class DomainB { 
    String email 
    Date dateCreated 
    Date lastUpdated 

    static belongsTo = [domainA: DomainA] 

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

Moje wymogiem jest wykaz wszystkich DomainA którego nazwa się zaczyna się od „M” i ostatni rekord domenyBs zawiera adres gmail w swojej usłudze e-mail.

Próbowałem createCriteria i hql, ale nie uzyskałem pożądanego rezultatu, być może robię coś nie tak.

Poniżej mój aktualny kod

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) 
    } 
} 

ale nie pozwala paginacji i sortowania.

Czy ktoś może mieć pomysł, aby uzyskać listę wszystkich DomainA, którego nazwa zaczyna się od "M", a ostatnie domenyB zawiera gmail w ich właściwości e-mail przy użyciu createCriteria lub hql lub w jakikolwiek inny sposób.

Odpowiedz

4

Ponieważ szukasz najnowszej wiadomości e-mail, musisz spojrzeć na datę maksymalną utworzoną na swojej domenie secondDomain. Możesz napisać to za pomocą HQL i używając executeQuery, aby przekazać swoje parametry paginacji. Po prostu upewnij się, że masz indeks na swoim 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: wystarczy uderzyć 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

To zapytanie daje mi pustą listę za każdym razem. – user1690588

+0

Czy masz dane, aby spełnić wymagania? zapytanie uwzględnia wielkość liter. Prawie użyłem twoich domen i zbudowałem kilka przykładowych danych i przetestowałem to. Sprawdzę dziś kod do github. – Alidad

+0

Utworzono instancję DomainA o nazwie "Manish' i instancja DomainB z adresem mailowym' test @ gmail.com', a zapytanie daje mi pustą listę. Oczekiwanie na repozytorium. Dzięki – user1690588

1

w Grails 2.4, powinieneś być w stanie zrobić coś takiego za pomocą nowej funkcjonalności podzapytanie skorelowane:

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

Niestety, nie mogliśmy przetestować naszej aplikacji w wersji 2.4, więc nie mogę potwierdzić, czy to zadziała.

+0

Używam Grails 2.3.5, Twoje zapytanie daje mi błąd, poprawiłem to za pomocą http://grails.org/doc/2.3.7/guide/GORM.html#where dokumentacji Queries. Twoje zapytanie daje nieprawidłowy wynik. Obejmuje to instancje DomainA, których najnowszą domeną B jest ot Gmail, ale mają gamil w starych rekordach. – user1690588