关于java:QueryDSL Left Join,附加条件为ON

QueryDSL Left Join with additional conditions in ON

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

1
2
3
4
5
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));

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

我已经基本离开了:

1
2
3
4
5
6
7
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和类似的搜索中获得的唯一其他结果。 (奇怪的是,即使在会话中启用了过滤器,过滤器甚至都不会影响查询...)

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

提前致谢!

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

浏览完文档后,似乎老式的博客表明querydsl具有leftJoinon()功能。为什么不再是这种情况?

SQLQuery(或HibernateSQLQuery或其他某种形式)具有on()函数,但leftJoin()接受RelationalPath< T >,而不是EntityPath< T >接受的EntityPath< T >。将QClasses强制转换为RelationalPath似乎是不可能的,所以这可能不是可行的方法。

更新2-我们正在使用2.9.0。使用on()会给出错误,就像它不存在一样。


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

这样就可以实现,

1
2
3
4
5
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()左连接。

更新:

从QueryDsl 3.0.0版本开始引入on()。因此,对于低于3.0.0的版本,它不可用。

我建议将您的版本至少升级到3.0.0,因为与旧版本相比,该API的功能更强大。更重要的是,我强烈建议您升级到最新的稳定版本(3.6.2),应该不会有任何问题,因为新的API支持以前的所有功能以及其他功能。

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

因此,对于较旧的版本,with()可以解决问题。这是一个有用的链接,其中包含更多详细信息。