不同于 4 个表的 Hibernate 列表

Hibernate list distinct from 4 tables

我们正在将 sql 中的一些遗留代码重写为 gorm with hibernate。 我偶然发现了一个问题——我们有 4 个不同的 table,映射到 4 个域 类。他们每个人都有一个 column/attribute 同名。 考虑以下(实际上很愚蠢)tables 以进行简化:

+-------------------+      +---------------------------+
| id | name |  role |      | id | position |    role   |
+-------------------+      +---------------------------+
|  1 | John | admin |      |  1 |  manager |     admin |
|  2 |  Bob |  user |      |  2 | sysadmin | superuser |
+-------------------+      +---------------------------+

从这些 tables/classes 中,我需要提取所有 distinct 角色。 使用 SQL,这可以通过 union:

轻松完成
SELECT role FROM Table1 UNION SELECT role FROM Table2 GROUP BY role

returns 想要的结果:[管理员、用户、超级用户]

现在我想知道,gorm/hibernate 如何做到这一点。一种可能的解决方案是使用以下两个标准:

first = Table1.createCriteria().list {
  projections {
    distinct "role"
  }
}
second = Table2.createCriteria().list {
  projections {
    distinct "role"
  }
}

然后浏览它们并过滤重复项。然而,这不是很有效,并且花费的时间几乎是原始查询的两倍(给定 4 tables,实际上导致 4 个查询)。 那么,对此最有效(时间和资源)的解决方案是什么?

//更新(回应@Emmanuel)

我无法控制数据库。我的访问权限是只读的。更可怕的是,table 中总共有大约 400 万行。这些数据会定期更新,并且每分钟都会添加新行,因此无法在某处创建新的 table。

GORM/Hibernate 不支持 UNION 查询。我的建议是规范化 tables,以便列(例如角色)位于单个 table 中,其他人通过外键引用它。使用您的 table 示例:

+-----------------+
+ id | role       +
+-----------------+
+  1 | admin      +
+  2 | user       +
+  3 | superuser  +
+-----------------+

+-------------------+
+ id | name |  role +
+-------------------+
+  1 | John |   1   +
+  2 |  Bob |   2   +
+-------------------+

+---------------------------+
+ id | position |    role   +
+---------------------------+
+  1 |  manager |     1     +
+  2 | sysadmin |     3     +
+---------------------------+

然后,当然,您可以简单地查询新域 class。

如果你不想使用 HQL,你可以这样做:

List<Role> list = Table1.createCriteria().list {
  projections {
    distinct "role"
    property "role"
  }
}
list = Table2.createCriteria().list {
  not{
    'in'('role', list)
  }
  projections {
    distinct "role"
    property "role"
  }
}