Querydsl如何实现多列求和 解决NumberPath无法直接相加报错问题
问题场景
STOCK表结构
id, bigint(20) available_quantity, int(11) allocation_quantity, int(11) stop_quantity, int(11) damage_quantity, int(11) standby_quantity, int(11)
待实现的SQL逻辑
需要查询库存各维度数量,同时计算可用、已分配、待调度三类数量的总和,对应SQL如下:
SELECT available_quantity, allocation_quantity, stop_quantity, damage_quantity, standby_quantity, available_quantity + allocation_quantity + standby_quantity FROM STOCK
遇到的报错
最初尝试直接用Java原生+运算符拼接Querydsl的字段表达式写求和逻辑,代码如下:
return queryFactory .select(new QStockResponseDto( stock.availableQuantity, stock.standbyQuantity, stock.allocationQuantity, stock.availableQuantity + stock.standbyQuantity + stock.allocationQuantity )).from(stock)
编译阶段抛出如下错误:
Operator '+' cannot be applied to 'com.querydsl.core.types.dsl.NumberPath<java.lang.Integer>', 'com.querydsl.core.types.dsl.NumberPath<java.lang.Integer>'
不清楚Querydsl中多列相加求和的正确写法。
错误原因
Querydsl生成的表字段类型是NumberPath<Integer>,属于查询表达式对象,不是Java原生的Integer基本类型/包装类,不支持直接使用Java原生的+、-这类算术运算符做运算,直接写会触发编译错误。
正确实现方式
Querydsl的数值表达式(NumberExpression)内置了专门的算术运算方法,多列相加需要调用add()方法做链式调用即可。
另外注意原实现还漏写了SQL中要求查询的stopQuantity、damageQuantity字段,且字段顺序和原SQL不匹配,修正后和原SQL查询逻辑完全对齐的代码如下:
return queryFactory .select(new QStockResponseDto( stock.availableQuantity, stock.allocationQuantity, stock.stopQuantity, stock.damageQuantity, stock.standbyQuantity, // 链式调用add实现多列求和 stock.availableQuantity .add(stock.allocationQuantity) .add(stock.standbyQuantity) )) .from(stock) .fetch();
空值兼容优化
如果业务中存在数量字段为null的场景,直接相加会导致最终求和结果为null,可以搭配coalesce()方法给字段设置默认值0,避免异常结果:
// 空值场景下默认按0计算 stock.availableQuantity.coalesce(0) .add(stock.allocationQuantity.coalesce(0)) .add(stock.standbyQuantity.coalesce(0))
内容的提问来源于stack exchange,提问作者Bohyun
相关产品推荐
相关产品推荐

