Grails,左外连接

标签 grails groovy left-join

我有两个域类用户和项目,如下所示

Users{
    String firstName
    String lastName
    String emailAddress
    static hasMany = [projects:Projects]
}



class Projects {
    String projectName
    String description
    Users projectLead
    Date completionDate
    static belongsTo = Users
}

这里completionDate == null表示项目尚未完成。

现在我想向每个用户发送有关其未完成项目的电子邮件提醒,如何编写查询来检索每个用户未完成的项目?

我正在考虑以下几行,但仍然无法继续。为了发送电子邮件,我需要用户的 emailid、所有不完整的项目及其名称

def users = Users.list()
       for(user in users){
           user.projects.find{it.completionDate==null}
       }

在这种情况下可以使用createCriteria吗?

最佳答案

我认为这应该有效:

def usersAndIncompleteProjects = Users.withCriteria {
    projects {
        isNull( completionDate )
    }
}

这应该只会返回具有不完整项目的用户,并且每个 Userprojects 属性将仅包含不完整的项目。如果您希望用户加载所有项目,我 believe you need to use an alias

<小时/>

测试...

给定用户类别:

package criteriatest

class User {
    String name

    static hasMany = [ projects: Project ]
}

以及项目类:

package criteriatest

class Project {
    String name
    Date completionDate

    static belongsTo = User

    static constraints = {
        completionDate( nullable:true )
    }
}

此集成测试通过(希望断言能够解释它)

package criteriatest

import grails.test.*

class UserTests extends GroovyTestCase {
    protected void setUp() {
        super.setUp()
        User.withSession { session ->
            def tim = new User( name:'tim' )
            def dave = new User( name:'dave' )

            [ tim, dave ]*.save()

            def project1 = new Project( name:'project 1', completionDate:null )
            def project2 = new Project( name:'project 2', completionDate:new Date() )

            tim.addToProjects project1
            tim.addToProjects project2

            [ project1, project2 ]*.save()

            session.flush()
            session.clear()
        }
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testQuery() {
        def usersAndIncompleteProjects = User.withCriteria {
            projects {
                isNull 'completionDate'
            }
            order 'name', 'asc'
        }

        // We get two users back (users with no projects get returned as well)
        assert usersAndIncompleteProjects.size() == 2

        // First user (dave) has no projects
        assert usersAndIncompleteProjects[0].projects.size() == 0

        // Second user (tim) has one project (with a null completionDate)
        assert usersAndIncompleteProjects[1].projects.size() == 1

        // Check it's the right project
        assert usersAndIncompleteProjects[1].projects*.name == [ 'project 1' ]
    }
}

(这是条件查询在此实例中执行的 SQL):

select
    this_.id as id1_1_,
    this_.version as version1_1_,
    this_.name as name1_1_,
    projects3_.user_projects_id as user1_3_,
    projects_a1_.id as project2_3_,
    projects_a1_.id as id0_0_,
    projects_a1_.version as version0_0_,
    projects_a1_.completion_date as completion3_0_0_,
    projects_a1_.name as name0_0_ 
from
    user this_ 
left outer join
    user_project projects3_ 
        on this_.id=projects3_.user_projects_id 
left outer join
    project projects_a1_ 
        on projects3_.project_id=projects_a1_.id 
where
    (
        projects_a1_.completion_date is null
    ) 
order by
    this_.name asc

关于Grails,左外连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6502718/

相关文章:

mysql - 从 LEFT JOINT 中仅选择一个 +mySQL

mysql - 优化Mysql查询Left Join

grails - 在Grails 2.0中为域对象使用分配的ID

mysql - Liquibase 更改日志前提条件

java - Groovy/Java 进程管理拦截/监听输出

grails - <g:each>的问题

java - Groovy JsonBuilder 在构建 Json 时添加了奇怪的字符序列

在 View 上访问时,传递给 View 的 Grails Controller 数据为空?

rest - Grails:如何在UrlMappings中为整个组设置参数

sql-server - 如果查询中包含内联接,为什么左联接会变成内联接?