如何在Grails / GORM / Hibernate中执行特定的SQL

时间:2016-07-08 02:04:05

标签: hibernate grails hql gorm

我在Grails中有类似的域名:

class Questao {

    static transients = [ "tags" ]

    String enunciado
    Double valorQuestao
    byte[] imagem
    public enum Tipo {
        ALTERNATIVAS,
        VF,
        SUBJETIVA
    }

    Tipo tipoQuestao

    static hasMany = [alternativas:Alternativas, assuntos: QuestaoAssunto, provas: Prova]

    static belongsTo = [Prova]

    static mapping = { enunciado type: 'text'}

    static constraints = {
        imagem nullable: true, maxSize: 160384
        alternativas nullable: true
    }
}

class QuestaoAssunto {

    Questao questao
    Assunto assunto

    static belongsTo = [Questao,Assunto]

}
class Assunto {

    String titulo

    static hasMany = [questoes:QuestaoAssunto]

    static belongsTo = [Questao]
}

我需要执行这个SQL:

select q.* from questao_assunto qa join questao q on q.id=qa.questao_id where assunto_id in (:assuntos_id) and q.tipo_questao = 'SUBJETIVA' GROUP BY q.id order by rand() limit 1;

:assuntos_id是一个像[5,6]

这样的数组

怎么能这个?

2 个答案:

答案 0 :(得分:1)

以下是如何从服务执行SQL的示例。可以在控制器中使用相同的方法:

import groovy.sql.Sql
import groovy.sql.GroovyRowResult

class SomeService {

    // Reference to default datasource.
    def dataSource

    List<GroovyRowResult> executeQuery(assuntosId) {

        final String query = '''\
                select q.* 
                from questao_assunto qa 
                join questao q on q.id=qa.questao_id 
                where assunto_id in (:assuntos_id) 
                and q.tipo_questao = 'SUBJETIVA' 
                group by q.id 
                order by rand() 
                limit 1
        '''

        // Create new Groovy SQL instance with injected DataSource.
        final Sql sql = new Sql(dataSource)

        final results = sql.rows(query, assuntos_id: assuntosId)
        results
    }     
}

答案 1 :(得分:1)

也许您有理由自己定义连接表,但我的方法是:

class Questao {

    static transients = [ "tags" ]

    String enunciado
    Double valorQuestao
    byte[] imagem
    public enum Tipo { ALTERNATIVAS, VF, SUBJETIVA }

    Tipo tipoQuestao

    static hasMany = [assuntos: Assunto]

    static mapping = { 
        enunciado type: 'text'
        assuntos joinTable:[name:"questao_assunto", key:'assunto_id' ]
    }

    static constraints = {
        imagem nullable: true, maxSize: 160384
    }
}

class Assunto {

    String titulo

    static hasMany = [questoes:Questao]

    static belongsTo = [Questao]

    static mapping = {
        questoes joinTable:[name:"questao_assunto", key:'questao_id' ]
    }
}

并执行SQL,我会尝试如下:

def records = Questao.findAll { 
    tipoQuestao == Questao.Tipo.SUBJETIVA 
    && assuntos { id in [1 as long,2 as long,3 as long] } 
}

或者如果您想订购并限制为1

def records = Questao.find(order: 'xxx') { ... }