Groovy 动态调用类和 find 方法不起作用?

发布于 2024-10-03 19:24:04 字数 416 浏览 8 评论 0原文

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

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

How can I usedynamic domain class name with find?

I trying to build a dynamic query similar to:

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

But it's not working.

If I'm trying this, all is fine:

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

How can I use dynamic domain class name with find?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七禾 2024-10-10 19:24:05

最简单的方法是使用 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])

The simplest way is to use the getDomainClass method:

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

Note that if you're trying to get a single instance by id, use get:

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

and if you want to get multiple instances and you have a list of ids, you can use getAll

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

Also it's a REALLY bad idea to use GStrings with property values embedded - Google 'SQL Injection'

For example to find a person by username:

String username = 'foo'
def person = domainClass.find(
    "from $domainClassName as m where m.username=:username",
    [username: username])
撧情箌佬 2024-10-10 19:24:05

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

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

You should be able to do this by explicitly using the GroovyClassLoader:

def domain = "DomainName"
def c = new GroovyClassLoader().loadClass(domain)
c.find('...').id
樱桃奶球 2024-10-10 19:24:05

动态获取 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

您还可以像在 Java 中一样使用 Class.forName()。使用 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 接口并完全避免这个问题。

The best way to get a Domain class dynamically is through the GrailsApplication object. Example:

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

You can also use Class.forName() just as you would in Java. Use the 3 parameter version and pass in the current thread context class loader:

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

Classloaders are an ugly topic in Java and JVM frameworks. In Grails, you almost always want to use the thread context classloader. But even better is to use the GrailsApplication interface and avoid the issue altogether.

欢烬 2024-10-10 19:24:05

使用 GrailsClassUtils

GrailsClassUtils.getShortName(DomainName)

获取班级名称,所以这应该有效...如果我理解这个问题

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

use GrailsClassUtils

GrailsClassUtils.getShortName(DomainName)

to get the name of the class, so this should work... if I understood the question

def domainClassName = GrailsClassUtils.getShortName(DomainName)
def ids = 1
DomainName.find("from ${domainClassName} as m where m.job = ${ids} ").id
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文