首先,我需要为冗长的帖子道歉,我为过于冗长而又始终不够清晰而苦恼。对于我的问题,我也进行了广泛的搜索,以寻求一种优雅的解决方案;如果您错过了它,请指导我。
某些背景:
我有一个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无法处理的。
我希望有人会知道更优雅的解决方案。并且请在本文中遗漏的任何地方都要求清楚。
最佳答案
好的,如果我了解您的问题:
可能有效的选项:
。
openAdJobs {
eq 'isOpen', true
eq 'publishedTo', "All External"
inList 'adLocation', Zip.list()
adCategory {
eq 'isActive', true
}
}
我认为可能有一个性能更好的替代方案,可以使用涉及用Exists子句替换inList的Subquery表达式,但是我不敢确定CriteriaBuilder / GORM Criteria是否支持。您可能必须进入Hibernate才能做到这一点,但我不确定该方法在命名查询中的表现如何。