首先,我需要为冗长的帖子道歉,我为过于冗长而又始终不够清晰而苦恼。对于我的问题,我也进行了广泛的搜索,以寻求一种优雅的解决方案;如果您错过了它,请指导我。

某些背景:
我有一个grails应用程序,它使用namedQueries作为一组标准结果集。该应用程序在我们的系统中找到未完成的广告工作订单,并将其发送到其他站点。最近,如果我希望继续使用namedQueries,对我来说,一个额外的要求已成为一个问题。

为了简单起见,我们假设一个域模型为

    class JobOrder {

  def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)

  }

  static namedQueries = {

    openAdJobs {
      eq 'isOpen', true
      eq 'publishedTo', "All External"
      adCategory {
        eq 'isActive', true
      }
    }

  static mapping = {
    table 'dbo.JOBORDER'
    version false
    id generator: 'identity', column: 'JOBORDERID'
    isOpen column: 'ISOPEN'
    publishedTo column: 'customText15'
    adLocation column: 'PUBLISHEDZIP'
    adCategory column: 'customInt3'
  }

  Boolean isOpen
  String publishedTo
  String adLocation
  ClientCorporation client
  AdCategory adCategory

  static constraints = {
    adLocation(size: 0..100)
  }

}

    class AdCategory {
  static mapping = {
    table 'dbo.AdCategory'
    version false
    id generator: 'identity', column: 'adCategory_ID'
    isActive column: 'active'
  }
}

    class Zip {
    static mapping = {
        table 'ZIP'
        version false
        id generator: 'identity', column: 'ZIPCODE'
        city  column: 'city'
        county  column: 'county'
        stateAbbr column: 'statecode'
    }

    String city
    String county
    String stateAbbr
}

我将从关注的当前namedQuery开始:
openAdJobs {
  eq 'isOpen', true
  eq 'publishedTo', "All External"
  adCategory {
    eq 'isActive', true
  }
}

此查询存在于我的JobOrder域对象中,该对象也与AdCategory域对象有关系。使用以下调用在多个位置调用命名查询:
def openJobs = JobOrder.openAdJobs

我的新问题:
现在,我需要确保不发布任何邮政编码无效的作业。我正在与一个不包含zip验证的产品集成,并且无法控制该产品的本机域模型。我们添加了一个独立的自定义Zip域对象。我一直在努力寻找一种方法,以在我的JobOrder对象中包含将与命名查询一起使用的代码,以完成以下查询将返回的内容:(我在dbvisualizer中针对sql db运行此查询)
  select * from dbo.JobOrder jo
  inner join dbo.AdCategory ac on jo.adCategory=ac.adCategory_ID
  where
  jo.isOpen=1
  and
  jo.publishedTo='All External'
  and
  ac.isActive=1
  and
  jo.publishedZip in (
        select zc.zipcode from dbo.Zip zc
  )

一个不太漂亮的解决方案:
我和几个同龄人获得所需结果集的唯一方法是在JobOrder对象中创建如下所示的方法:
def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)
}

当然,除非实例化JobOrder,否则该方法不可用。由于我此时实际上正在尝试构建我的JobOrders列表,因此有一个非常令人讨厌的技巧来获取我的结果集。我将需要获取一个已知的好的JobOrder(或创建一个),以便可以调用getOpenAdJobsSql()方法。

就像是:
def jo = JobOrder.get(2)
def rset = jo.openAdJobsSql

将需要添加到我当前称为 openAdJobs 命名查询的所有位置(目前有9种或更多用法)。甚至考虑使用这种方法都会给我带来精神上的警告,但我发现没有其他方法可以添加其他功能。

同样,最终我希望调用一个命名查询,但是附加的邮政编码sql似乎是GORM + hibernate无法处理的。

我希望有人会知道更优雅的解决方案。并且请在本文中遗漏的任何地方都要求清楚。

最佳答案

好的,如果我了解您的问题:

  • JobOrder,更具体地说是底层的JOBORDER表和填充该表的机制,是第三方产品。您也不能更改。
  • JOBORDER中的行可能包含ZIP表中不存在的PUBLISHEDZIP值。
  • 您当前的GORM模型不包含JOBORDER和ZIP之间的关系,因此您不能使用Criteria / HQL选择仅包含有效邮政编码的数据子集。

  • 可能有效的选项:
  • 将您描述的方法设为静态,因此您无需实例化基础类的对象。
  • 在您的命名查询上使用inList限制(我尚未测试过,但似乎应该可以使用)。


  • openAdJobs {
        eq 'isOpen', true
        eq 'publishedTo', "All External"
        inList 'adLocation', Zip.list()
        adCategory {
          eq 'isActive', true
       }
     }
    

    我认为可能有一个性能更好的替代方案,可以使用涉及用Exists子句替换inList的Subquery表达式,但是我不敢确定CriteriaBuilder / GORM Criteria是否支持。您可能必须进入Hibernate才能做到这一点,但我不确定该方法在命名查询中的表现如何。

    10-05 23:52