【问题标题】:QueryDSL Left Join with additional conditions in ONQueryDSL Left Join,附加条件为 ON
【发布时间】:2015-05-05 03:52:24
【问题描述】:

是否可以在 QueryDSL 中进行以下查询?

SELECT p.*
FROM parts_table p LEFT JOIN inventory_balance_table i ON 
    (p.part_no = i.part_no 
     AND i.month = MONTH(CURRENT_DATE) 
     AND i.year = YEAR(CURRENT_DATE));

库存余额存储每个零件号/月/年的库存数据;我需要当前年份和月份的唯一数据。

我已经掌握了基本的左连接:

QPartsTable qParts = QPartsTable.partsTable;
QInventoryBalance qBalance = QInventoryBalance.inventoryBalance;

JPAQuery q = new JPAQuery(em);
q.from(qParts).leftJoin(qParts.inventoryBalance, qBalance);
q.where(...);
List<Part> list = q.list(qParts);

生成正确的 sql,但仅加入零件号。

检查生成的零件是否有库存(除其他外)。左连接是必要的,因为我仍然需要还没有库存条目的零件(例如新零件)。左连接将获得那些没有匹配库存余额的行,但在查询的 where 子句中添加 month = MONTH(CURRENT_DATE) 等会删除没有库存余额的行(因为它们没有年/月数据)。

出于同样的原因@Where@Filter 将从生成的部件列表中删除这些部件并且不适用。可悲的是,@Filter@Where 是我在 Google 和 SO 上搜索得到的唯一其他结果。 (奇怪的是,即使在会话中启用了过滤器,过滤器也不会影响查询......)

最简单的解决方案是我最初的问题:如何将上述 SQL 转换为 QueryDSL?一般来说,是否可以向左连接的 ON 子句添加更多和/或自定义条件?这个问题的替代解决方案是什么?

提前致谢!


更新 - 一个后续问题和一个观察:(也许这应该完全是一个新问题?)

查看文档后,似乎较早的展示 querydsl 的博客具有 leftJoinon() 函数。为什么现在不再这样了?

SQLQuery(或 HibernateSQLQuery 或其他一些变体)具有 on() 函数,但 leftJoin() 接受 RelationalPath&lt;T&gt;,而不是 EntityPath&lt;T&gt;JPAQuery 那样。将 QClasses 转换为 RelationalPath 似乎是不可能的,所以这可能不是要走的路……


更新 2 - 我们使用的是 2.9.0。使用on() 会报错,就像它不存在一样...

【问题讨论】:

  • 那是因为2.9.0中不存在。

标签: java left-join querydsl


【解决方案1】:

可以在QueryDSL 中使用on(),包括最新版本。 JPAQuery 也支持on() 谓词。

这样就可以实现了,

QPartsTable qParts = QPartsTable.partsTable;
QInventoryBalance qBalance = QInventoryBalance.inventoryBalance;

JPAQuery q = new JPAQuery(em);
q.from(qParts).leftJoin(qParts.inventoryBalance, qBalance).on(qBalance.month.eq(yourMonth).and(qBalance.year.eq(yourYear))).list(qParts);

JPAQuery 实现了JPQLCommonQuery 接口,因此它拥有所有必要的方法。

这里是来自 QueryDSL 最新版本的文档,其中使用 on() 示例进行左连接。

更新:

on() 从 QueryDsl 3.0.0 版本开始引入。所以对于 3.0.0 以下的版本是不可用的。

我建议至少将您的版本升级到 3.0.0,因为与旧版本相比,API 更加强大。更重要的是,我强烈建议升级到最新的稳定版本(3.6.2),应该没有任何问题,因为新的 API 像以前一样支持一切,并具有附加功能。

更新 2: 正如评论中提到的@Cezille07,在旧版本中有with() 替代on()。正如我们从 issue 看到的那样,with() 稍后已被替换为 on()

所以对于旧版本with() 可以解决问题。这是一个有用的link,提供更多详细信息。

【讨论】:

  • 我们使用的是 querydsl 2.9.0。它在那个链接中,但是当我使用on(...) 时,它有一个错误“JPAQuery 类型的方法 on(BooleanExpression) 未定义”。 on 甚至不会出现在 JPAQuery 的自动完成函数列表中。
  • 现在我们知道问题所在了:) 2.9.0 不支持on 表达式,你应该至少升级一个版本到3.0.0。请查看我编辑的答案,我在其中包含了此信息。希望对您有所帮助。
  • 感谢您的信息!经过一番挖掘,对于旧版本,with 的功能与 on 的功能相同。 link能否请您补充一下,我会接受您的回答。
  • 非常有用的信息!谢谢,我已将其添加到我对未来访客的回答中。伟大的发现,不知道。
猜你喜欢
  • 2021-09-13
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
  • 2022-10-17
  • 2022-08-18
相关资源
最近更新 更多