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
      的一种简写方式),则第一个想法非常有效。非常感谢。我想知道是让控制器很小还是将逻辑从服务移动到它(当然性能更好!)…我不认为将代码从控制器移动到服务会带来任何性能好处。。。如果有的话,调用服务层的代价可以忽略不计。为了可重用性、可读性等,您需要将逻辑移动到服务中。