是否可以在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,但只会连接部件编号。
生成的部件将检查库存可用性(除其他外)。左联接是必要的,因为我仍然需要那些还没有库存条目的部件(例如,新的部分)。Left将获得那些没有匹配的库存余额,但是将month = MONTH(CURRENT_DATE)
等添加到where子句中将删除没有库存余额的行(因为它们没有年份/月数据)。
出于同样的原因,@Where
和@Filter
将从结果部件列表中删除这些部件,并且不适用。遗憾的是,@Filter
和@Where
是我在谷歌和这里搜索得到的唯一其他结果。(奇怪的是,即使会话中启用了筛选器,过滤器也不会影响查询.)
最简单的解决方案将是我最初的问题:如何将上述SQL转换为QueryDSL?通常,是否可以向左联接的ON子句添加更多和/或自定义条件?解决这一问题的替代办法是什么?
提前感谢!
Update -一个后续问题和一个观察:(也许这应该是一个全新的问题吗?)
在查看了文档之后,那些展示querydsl的老博客似乎为leftJoin
提供了leftJoin
函数,为什么不再是这种情况了?
SQLQuery
(或HibernateSQLQuery
或其他一些变种)具有on()函数,但是leftJoin()接受RelationalPath<T>
,而不是JPAQuery
那样的EntityPath<T>
。把QClasses投给RelationalPath
似乎是不可能的,所以这可能不是一条路.
更新2 -我们使用的是2.9.0。使用on()
会产生一个错误,就像它不存在.
发布于 2015-03-04 11:35:34
可以在on()
中使用QueryDSL,包括最新版本。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: As @Cezille07在评论中提到,在旧版本中,on()
有一个with()
替代方案。正如我们从问题中看到的那样,with()
后来已经被on()
取代了。
因此,对于较早的版本,with()
做了这方面的工作。这是一个有用的链接和更多的细节。
https://stackoverflow.com/questions/28849713
复制相似问题