搜索记录基于最新记录的非常关系

MKB*_*MKB 6 grails grails-domain-class grails-2.3

我有两个域名

class DomainA {
    String name
    Date dateCreated
    Date lastUpdated

    static transients = ['email']

    static hasMany = [domainBs: DomainB]

    public String getEmail() {
        DomainB.mostRecentRecord(this).get()?.email
    }
}
Run Code Online (Sandbox Code Playgroud)

class DomainB {
    String email
    Date dateCreated
    Date lastUpdated

    static belongsTo = [domainA: DomainA]

    static namedQueries = {
        mostRecentRecord { domainA ->
            eq 'domainA', domainA
            order('dateCreated', 'desc')
            maxResults(1)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的要求是获取名称以"M"开头的所有DomainA的列表,并且最新的domainBs记录在其email属性中包含gmail.

我尝试过createCriteria,hql但没有得到理想的结果,可能是我做错了什么.

以下是我目前的代码

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

但它不允许分页和排序.

有人能有什么主意,让所有DomainA中,其名称以"M"开头,最新domainBs使用包含在他们的电子邮件Gmail的财产清单createCriteriahql或任何其他方式.

Ali*_*dad 4

由于您正在查找最新的电子邮件,因此您需要查看第二个域上的最大创建日期。您可以使用 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]) 
Run Code Online (Sandbox Code Playgroud)

示例代码:只需点击第一个DomainController

        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%'])
Run Code Online (Sandbox Code Playgroud)