如何使用grails GORM做多个字段匹配的左外连接?

时间:2015-03-06 20:44:56

标签: grails gorm

我们需要在grails项目中执行以下操作:

select * from message m  
LEFT JOIN votes v ON v.message_id = m.id and v.user_id = 1 
where parent_id is null;

域类非常简单:

class Message {

    String text
    User user

    static belongsTo = [parent:Message]

    static hasMany = [messages:Message, votes:Votes]

    static constraints = {
        parent nullable: true
    }

    static mapping = {
        votes lazy: false
    }
}

class Votes {

    User user
    Message message
    int vote = 0

    static belongsTo = [user:User, message:Message]

    static constraints = {
    }

    static mapping = {
        vote defaultValue: 0
    }
}

到目前为止,我们能够使v.message_id = m.id条件生效,但无法将and v.user_id = 1条件添加到LEFT OUTER JOIN。

这是控制器代码:

    def test = Message.withCriteria {

        isNull('parent')
        createAlias('votes', 'v', CriteriaSpecification.LEFT_JOIN)

    } 

任何想法如何做到这一点?

3 个答案:

答案 0 :(得分:3)

我们弄清楚了,正确的代码是

def test = Message.withCriteria {
        isNull('parent')        
        createAlias('votes', 'v', CriteriaSpecification.LEFT_JOIN,   Restrictions.eq("v.user.id", 1 as long));
    }

这将根据需要生成SQL查询。

答案 1 :(得分:1)

为什么你不能在常规的eq限制中使用第二个条件?你的sql与:select * from message m LEFT JOIN votes v ON v.message_id = m.id where parent_id is null and v.user_id = 1;

相同
def test = Message.withCriteria {
    isNull('parent')
    createAlias('votes', 'v', CriteriaSpecification.LEFT_JOIN)
    eq 'v.user', User.get(1)
} 

或者

def test = Message.withCriteria {
    isNull('parent')
    createAlias('votes', 'v', CriteriaSpecification.LEFT_JOIN)
    createAlias('v.user', 'u', CriteriaSpecification.LEFT_JOIN)
    eq 'u.id', 1
} 

答案 2 :(得分:0)

适用于使用Grails 3的任何人

import org.hibernate.criterion.Restrictions

...
...

def test = Message.withCriteria {
        isNull('parent')        
        createAlias('votes', 'v', JoinType.LEFT_OUTER_JOIN, Restrictions.eq("v.user.id", 1 as long));
    }