3

我需要一种在 Grails/Hibernate 中执行“全部”标准查询的方法。标准的“in”限制就是我所说的“in any”限制。

举例来说...

序言

以与另一个域类“Perils”具有多对多关联的域类“Knights”为例。课程很简单...

class Knight {
  String name
  static hasMany = [perils:Peril]   
}

class Peril {
  String name
  static hasMany = [knights:Knight]
  static belongsTo = Knight
}

表格内容看起来像这样......

    骑士
    1 亚瑟,不列颠国王(严格来说不是骑士。我知道,我知道。)
    2 聪明的贝德维尔爵士
    3 勇敢的兰斯洛特爵士
    4 不像兰斯洛特爵士那样勇敢的罗宾爵士
    5 纯洁的加拉哈德爵士

    危险
    1 黑骑士
    2 说 Ni 的骑士
    3 三头巨人
    4 沼泽城堡
    5 炭疽城堡
    6 卡班诺兔

    Knights_Perils
    1, 1 // 亚瑟与黑骑士战斗
    1, 2 // 亚瑟与说 ni 的骑士战斗
    2, 2 //bedevere 与说 ni 的骑士战斗
    4, 3 // 罗宾逃离三头巨人
    3, 4 // 兰斯洛特突袭沼泽城堡
    5, 5 // 加拉哈德参观炭疽城堡
    3, 5 // 兰斯洛特从炭疽城堡“拯救”加拉哈德
    1, 6 // 所有骑士都与杀手兔战斗
    2, 6 // ...
    3, 6 // ...
    4, 6 // ...
    5, 6 // ...

我提出了一个表单,它提供了用于搜索关联的复选框......

    选择危险并寻找骑士...
     [ ] 黑骑士 (id 1)
     []说Ni的骑士(id 2)
     [ ] 三头巨人 (id 3)
     [x] 沼泽城堡 (id 4)
     [x] 炭疽城堡 (id 5)
     [x] 杀手兔(id 6)

     [搜索]

我这样查询:

def query = Knights.createQuery()
query.list(max: params.max, offset: params.offset) {
  if(params.perils) perils { 'in' ('id', params.list('perils')*.toLong()) }
}

这产生了我所说的“任何”结果。Knight 与已检查危险列表中的“任何”关联。在上面表格中的3个检查危险的情况下,所有的骑士......

    亚瑟 - 打兔子
    Bedevere - 与兔子战斗
    兰斯洛特 - 沼泽城堡、炭疽城堡、打兔子
    罗宾 - 打兔子
    Galahad - 城堡炭疽病,与兔子战斗

问题

我正在寻找类似于“in”的 Hibernate/Grails 标准限制,但它将查询“in all”。换句话说,Knight 与列表中“全部”检查的危险有关联。有了这个限制,以及上面相同的表单输入,我希望结果只有

    兰斯洛特 - 沼泽城堡、炭疽城堡、打兔子

Hibernate 标准“in”限制是否有“in all”版本?

请记住,我想使用 CriteriaQuery(在 Hibernate 或 Grails 方言中)来执行此操作,而不是直接使用 SQL 或 HQL。

关于如何解决这个问题的任何指示?

谢谢!

  • 加里
4

1 回答 1

1

好问题。也许有更好的选择,因为我不知道 SQL/HQL 的每个方面,但以下子句:

all the selected perils are in the knight's perils

也可以这样表达

there is no peril in the selected perils that is not in the knight's perils

因此,在 HQL 中,您可以这样表示:

select knight from Knight knight
where not exists (select peril.id from Peril peril 
                  where peril.id in :selectedPerilIds
                  and peril.id not in (select peril2.id from Peril peril2
                                       where peril2.knight.id = knight.id))
于 2012-05-04T07:30:52.783 回答