QueryDSL左加入ON中的附加条件

时间:2015-03-04 08:27:57

标签: java left-join querydsl

是否可以在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,但只加入了部件号。

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

出于同样的原因,@Where@Filter会从结果部分列表中删除这些部分,但不适用。遗憾的是,@Filter@Where是我在谷歌和SO搜索中获得的唯一其他结果。 (奇怪的是,即使在会话中启用了过滤器,过滤器也不会影响查询...)

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

提前致谢!


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

在浏览文档后,似乎较早的博客证明了querydsl具有on()的{​​{1}}功能。为什么不再是这种情况?

leftJoin(或SQLQuery或其他一些品种)有on()函数,但leftJoin()接受HibernateSQLQuery,而RelationalPath<T>接受EntityPath<T> }。将QClasses转换为JPAQuery似乎是不可能的,因此可能不是这样......


更新2 - 我们正在使用2.9.0。使用RelationalPath会产生错误,就像它不存在一样......

1 个答案:

答案 0 :(得分:7)

可以在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接口,与其他接口一样,它具有所有必要的方法。

以下是使用on()示例的QueryDSL最新版本与左连接的文档。

<强>更新

自QueryDsl 3.0.0版本以来已经引入了

on()。因此,对于低于3.0.0的版本,它不可用。

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

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

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