0

我正在使用 hibernate/hql 来创建我的查询。现在我遇到了一个问题,我已经坚持了好几个小时,要了解这里的情况是我的周围环境:

我有 3 个需要从中获取信息的表,而连接/分配表总共有 5 个。我需要的信息是Key,Type和SourceFile,但是这里的特殊情况是sql会在导入新数据时完成,所以我想先检查数据是否已经存在,或者部分存在。我的查询需要始终给我密钥,无论是什么类型或 SourceFile,如果密钥本身已经在数据库中,那么我只需要密钥而不是其他信息。(密钥匹配,但 SourceFile 和 Type 不匹配,所以我只想要返回密钥)如果密钥与完全相同的 Type 和 SourceFile 存在,我想获取所有信息。

这些表格是:

(注意:FK_K_ID 保存为带有 name 键的对象,FK_S_ID 保存为 Source,FK_T_ID 保存为 Type)

钥匙:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| K_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| key         | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

密钥类型:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| KT_ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| FK_K_ID     | bigint(20)   | NO   |     | NULL    |                |
| FK_T_ID     | bigint(20)   | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

类型:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| T_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | NO   |     | NULL    |                |
| description | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

关键来源:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| KS_ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| FK_K_ID     | bigint(20)   | NO   |     | NULL    |                |
| FK_S_ID     | bigint(20)   | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

资源:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| S_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| sourceFile  | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

这是我到目前为止所尝试的:

from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and ( kt.Type in (...) or kt is null )

这个问题是,它有点像我想要的。但我只获取数据库中的所有键,并且仅在匹配的地方获取 KeyType,否则为空。我不想得到所有的钥匙,我只想得到我要求的钥匙。

from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )

老实说,我什至不知道我在这里尝试了什么。我想我试图优化第一个查询,只给出我要求的键。

from KeyType kt
right outer join fetch kt.Key k
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )

我也尝试使用 fetch 这样或其他变体,但没有像我需要的那样工作。

from Key k
left outer join KeyType kt on kt.Key.id = k.id
left outer join KeySource ks on ks.Key.id = k.id
inner join Source s on ks.Source.id = s.id
where k.deleted = false
and k.name in (...)
and ( kt.appType in (...) or kt is null )
and ( s.SourceFile in (...) or s is null )

正如预期的那样,这不起作用。我的意思是看到它不能工作很简单,但如果你不能坚持下去,你会尝试很多。

我尝试了更多的查询组合和变体,但没有运气。第一个查询是我得到的最接近的。我希望有人能帮助我。

PS:我现在无法更改映射或实体。我必须用我得到的东西工作。

更新:

好的,所以我非常接近解决问题。我的查询现在看起来像这样:

select k, case when kt.Type not in (...) then null
               else 1 end
from KeyType kt
join kt.Key k
where k.name in (...)

现在我唯一想做的就是将 1 与实际对象交换。但是如果我这样做,我会收到错误“org.hibernate.exception.GenericJDBCException:无法执行查询”(在 oracle db 上运行)

有人可以告诉我如何解决吗?

4

1 回答 1

0

对于我的情况和围绕我想做的方式来说是不可能的。

所以我再次询问了同事,我们得出了我们必须在单个查询中完成的解决方案。

只是对任何通过这篇文章的人说这个,并且有相同的表配置/问题。

于 2016-08-04T08:32:29.740 回答