我有两个域类用户和项目,如下面的
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?
答案 0 :(得分:4)
我认为这应该有效:
def usersAndIncompleteProjects = Users.withCriteria {
projects {
isNull( completionDate )
}
}
这应该只返回具有不完整项目的用户,并且每个projects
的{{1}}属性仅包含不完整的项目。如果您希望用户加载所有项目,我believe you need to use an alias
测试... 的
鉴于User类:
User
项目类:
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 )
}
}
(这是条件查询在此实例中执行的sql):
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' ]
}
}
答案 1 :(得分:3)
我不确定此问题是否需要左连接,除非您要包含具有空用户的项目。为什么不选择具有空完成日期的所有项目并加入对用户?
在HQL中,它看起来像这样:
Projects.executeQuery('from Projects p join p.projectLead u where p.completionDate is null')
您可以在条件查询中执行类似操作:
Projects.withCriteria {
isNull('completionDate')
join('projectLead')
}