Pergunta

Estou tentando criar uma consulta dinâmica semelhante a:

def domain = DomainName
def ids = 1
def domainClass = "$domain" as Class
domainClass.find("from ${domain} as m where m.job = ${ids} ").id

Mas não está funcionando.

Se estou tentando isso, está tudo bem:

def domain = DomainName
def ids = 1
DomainName.find("from ${domain} as m where m.job = ${ids} ").id

Como posso usar o nome da classe de domínio dinâmico com o encontro?

Foi útil?

Solução

A maneira mais simples é usar o getDomainClass método:

String domainClassName = 'com.foo.bar.Person'
def ids = 1
def domainClass = grailsApplication.getDomainClass(domainClassName).clazz
domainClass.find("from $domainClassName as m where m.job = ${ids} ").id

Observe que se você está tentando obter uma única instância por id, use get:

long id = 1234
def person = domainClass.get(id)

E se você quiser obter várias instâncias e tiver uma lista de IDs, pode usar o GetAll

def ids = [1,2,3,4,5]
def people = domainClass.getAll(ids)

Também é um VERDADE Idéia ruim para usar GStrings com valores de propriedades incorporados - Google 'SQL Injeção'

Por exemplo, para encontrar uma pessoa pelo nome de usuário:

String username = 'foo'
def person = domainClass.find(
    "from $domainClassName as m where m.username=:username",
    [username: username])

Outras dicas

Você deve ser capaz de fazer isso explicitamente usando o groovyclassloader:

def domain = "DomainName"
def c = new GroovyClassLoader().loadClass(domain)
c.find('...').id

A melhor maneira de obter uma classe de domínio dinamicamente é através do objeto GrailSapplication. Exemplo:

import org.codehaus.groovy.grails.commons.ApplicationHolder

def domainName = "full.package.DomainName"
def domainGrailsClass = ApplicationHolder.application.getArtefact("Domain", domainName)
def domainClass = domainGrailsClass.getClazz()
domainClass.find("from ${domainGrailsClass.name} as m where m.job = ${ids}").id

Você também pode usar Class.forName() Assim como faria em Java. Use a versão de 3 parâmetros e passe no carregador de classe de contexto de encadeamento atual:

import grails.util.GrailsNameUtils

def domainName = "full.package.DomainName"
def domainClass = Class.forName(domainName, true, Thread.currentThread().getContextClassLoader())
domainClass.find("from ${GrailsNameUtils.getShortName(domainName)} as m where m.job = ${ids}").id

Os carregadores de classe são um tópico feio nas estruturas Java e JVM. Nos Grails, você quase sempre deseja usar o carregador de classe de contexto do thread. Mas ainda melhor é usar a interface do GrailSapplication e evitar completamente o problema.

usar Grailsclassutils

GrailsClassUtils.getShortName(DomainName)

Para obter o nome da classe, então isso deve funcionar ... se eu entendesse a pergunta

def domainClassName = GrailsClassUtils.getShortName(DomainName)
def ids = 1
DomainName.find("from ${domainClassName} as m where m.job = ${ids} ").id
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top