Grails 如何从另一个查询的结果执行查询
它的工作原理是:Grails 如何从另一个查询的结果执行查询,grails,Grails,它的工作原理是: def c = DomainClass.createCriteria() def results = c.list { ge("property1", params.param1.toInteger()) le("property2", params.param2.toFloat()) } 我们想再添加一个条件: 尝试1)在createCriteria之前: def preResults = DomainClass.getAllByProperty3Great
def c = DomainClass.createCriteria()
def results = c.list {
ge("property1", params.param1.toInteger())
le("property2", params.param2.toFloat())
}
我们想再添加一个条件:
尝试1)在createCriteria之前:
def preResults = DomainClass.getAllByProperty3GreaterThan(0)
def c = preResults.createCriteria()
...
...
postResults = results.getAllByProperty3GreaterThan(0)
它给出错误:没有方法的签名:java.util.ArrayList.createCriteria()适用于参数类型:()值:[]
尝试2)在createCriteria之后:
def preResults = DomainClass.getAllByProperty3GreaterThan(0)
def c = preResults.createCriteria()
...
...
postResults = results.getAllByProperty3GreaterThan(0)
它给出错误:没有方法的签名:java.util.ArrayList.getAllByProperty3GreaterThan()适用于参数类型:(java.lang.Integer)值:[0]
不包含createCriteria中的所有内容的原因是preResults(或postResults)是服务函数的结果。。。为了简化,我省略了这里的服务(并更改了变量的名称)。您不能像这样通过查找者(或标准)链接
查找对象。。。对域类调用第一个查找器(这很好,因为查找器是域类的方法),但它返回一个PersistentSet
,它上面没有findBy
方法
有两件事(我能想到)你可以尝试:
- 首先使用
criteria
,然后使用results.findAll{it.property3}
,但这会将所有结果提取到内存中并在内存中进行过滤
- 创建一个命名查询(您可以链接这些查询,并在末尾放置一个
findBy
)。。。类似这样的内容DomainClass.myNamedQuery.findallbyproperty3greater大于(0)
。命名查询应该执行问题中的条件所执行的操作。请参阅有关命名查询的详细信息
即使您的服务方法与wrt
property3做了相同的事情,下面这样做的问题是什么
def results = c.list {
ge("property1", params.param1.toInteger())
le("property2", params.param2.toFloat())
gt("property3", 0)
}
除了在上述标准中无法表示的微不足道的一行之外,服务方法中是否还有其他逻辑
DomainClass.GetAllByProperty3Greater大于(0)
我只是想知道坚持服务方法背后的理由。它可以用一个标准来表示,但控制器会成长很多,代码也会变得不那么清晰。该服务的调用类似于:postResults=AdvancedFilterService.function(results,params.param3)
您希望我在这里复制并粘贴服务的真实代码吗?“我不明白第一个想法,@zoran119。你能给我举个例子吗?第二个想法应该行得通(如果我能够将命名查询从控制器传递到服务),但它看起来并不是为了这个目的而做的…:/您不需要将命名查询从控制器传递到服务。您只需在域类中声明命名查询(根据我链接的文档),并在服务中使用它,如下所示:DomainClass.myNamedQuery.findAllByProperty3GreaterThan(0)
。。。首先执行def c=DomainClass.createCriteria()
,然后执行def results=c.list{/*stuff*/}
,最后执行def filteredResults=results.findAll{it.property3}
。请注意,it.property3
将返回true
,如果其值大于零(这只是编写it.property3>0
的一种简写方式),则第一个想法非常有效。非常感谢。我想知道是让控制器很小还是将逻辑从服务移动到它(当然性能更好!)…我不认为将代码从控制器移动到服务会带来任何性能好处。。。如果有的话,调用服务层的代价可以忽略不计。为了可重用性、可读性等,您需要将逻辑移动到服务中。