2

我试图建立一个类似于以下的动态查询:

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

但它不起作用。

如果我正在尝试这个,一切都很好:

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

如何在 find 中使用动态域类名?

4

4 回答 4

9

最简单的方法是使用getDomainClass方法:

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

请注意,如果您尝试通过 id 获取单个实例,请使用get

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

如果你想获取多个实例并且你有一个 id 列表,你可以使用 getAll

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

此外,使用嵌入属性值的 GStrings 也是一个非常糟糕的主意 - Google 'SQL Injection '

例如通过用户名查找人:

String username = 'foo'
def person = domainClass.find(
    "from $domainClassName as m where m.username=:username",
    [username: username])
于 2010-11-20T00:57:14.297 回答
1

您应该能够通过显式使用 GroovyClassLoader 来做到这一点:

def domain = "DomainName"
def c = new GroovyClassLoader().loadClass(domain)
c.find('...').id
于 2010-11-19T23:39:58.807 回答
1

动态获取 Domain 类的最佳方法是通过 GrailsApplication 对象。例子:

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

您也可以Class.forName()像在 Java 中一样使用。使用 3 参数版本并传入当前线程上下文类加载器:

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

类加载器在 Java 和 JVM 框架中是一个丑陋的话题。在 Grails 中,您几乎总是希望使用线程上下文类加载器。但更好的是使用 GrailsApplication 接口并完全避免该问题。

于 2010-11-20T00:21:28.257 回答
0

使用GrailsClassUtils

GrailsClassUtils.getShortName(DomainName)

获取班级的名称,所以这应该可以工作......如果我理解这个问题

def domainClassName = GrailsClassUtils.getShortName(DomainName)
def ids = 1
DomainName.find("from ${domainClassName} as m where m.job = ${ids} ").id
于 2010-11-19T23:27:48.330 回答