赛派号

水龙头前置过滤器多少钱 LambdaQueryWrapper使用 group分组、sum聚合函数 进行统计,并分页排序

首先,我们要知道,其实LambdaQueryWrapper是无法使用sum聚合函数的,因为LambdaQueryWrapper的select()方法无法传入字符串,但你有张良计,我有过墙梯,我们其实可以迂回来做。

先使用QueryWrapper,拼接我们需要的select,然后再转成LambdaQueryWrapper,具体如下:

order对象:(简单写需要的东西)

@Data @TableName("t_order") public class OrderModel { /** * 商户号 */ private String merNo; /** * 订单号 */ private BigDecimal orderId; /** * 手续费 */ private BigDecimal feeAmt; /** * 到账金额 */ private BigDecimal arrivalAmt; /** * 交易时间 */ private LocalDate tradeDate; }

代码如下:

Page page = orderService.page(new Page(1, 20), new QueryWrapper() .select(" SUM(fee_amt) AS fee_amt, SUM(arrival_amt) AS arrival_amt, mer_no ") .lambda() .between(StrUtil.isNotBlank(commandReq.getStartDate()) && StrUtil.isNotBlank(commandReq.getEndDate()), OrderModel::getTradeDate, StrUtil.isNotBlank(startDateStr) ? LocalDate.parse(startDateStr) : null, StrUtil.isNotBlank(endDateStr) ? LocalDate.parse(cendDateStr) : null) .groupBy(OrderModel::getMerNo));

分页查询,按照商户号进行分组,手续费和到账金额进行汇总,如果时间不为空,用between范围查询。 先用QueryWrapper处理掉聚合函数,然后再用.lambda()转成LambdaQueryWrapper,保证下面能用lambda写法。 SUM(fee_amt)直接丢在fee_amt里,就不用去新加属性了,如果不想,可以再加个对象里补个汇总字段。

@TableField(exist = false) private BigDecimal FeeTotalAmt;

进行扩展,如果我们想多查一个订单号orderNo,第一种写法可以这样写:

.select(" SUM(fee_amt) AS fee_amt, SUM(arrival_amt) AS arrival_amt, mer_no, order_no ") .lambda()

但是这样写的坏处就是,不够优雅,而且如果在ja里改了属性名,会导致查询出问题,这也是我们想用LambdaQueryWrapper的原因。

但如果按照下面这种写法,也存在问题:

.select(" SUM(fee_amt) AS fee_amt, SUM(arrival_amt) AS arrival_amt, mer_no ") .lambda() .select(OrderModel::getOrderNo)

这样写会导致我们在QueryWrapper写的select被LambdaQueryWrapper覆盖调。所以第二种做法行不通,但不想用第一种写法,想用lambda,那么就得解决第二种写法出现的问题。

通过查看LambdaQueryWrapper的select方法,发现它是使用SFunction接收参数,并把参数使用stream流转成字符串。 在这里插入图片描述 在这里插入图片描述 那么,具体思路就有了,我们把SFunction根据流的方式,转成字符串,代码如下:

/** * 处理sql查询字段名 * @param columns * @return */ private String getParamSql(SFunction... columns) { return Arrays.stream(columns).map(c -> StrUtil.toUnderlineCase(LambdaUtils.getName(c))).collect(Collectors.joining(StringPool.COMMA, StringPool.SPACE, StringPool.SPACE)); }

通过Arrays.stream()为可变数组创建流,然后使用LambdaUtils.getName()方法获取属性名,再用StrUtil.toUnderlineCase()把属性名从,小驼峰转成下划线,最后用.collect(Collectors.joining())拼成字符串,用逗号分隔,前后加空格。

然后我们就可以通过这个方法使用lambda啦,因为入参是用可变数组,所以所以传入多个,这里只传入一个orderNo。

.select(" SUM(fee_amt) AS fee_amt, SUM(arrival_amt) AS arrival_amt, mer_no ", getParamSql(OrderModel::getOrderNo)) .lambda()

完整代码如下:

Page page = orderService.page(new Page(1, 20), new QueryWrapper() .select(" SUM(fee_amt) AS fee_amt, SUM(arrival_amt) AS arrival_amt, mer_no ", getParamSql(OrderModel::getOrderNo)) .lambda() .between(StrUtil.isNotBlank(commandReq.getStartDate()) && StrUtil.isNotBlank(commandReq.getEndDate()), OrderModel::getTradeDate, StrUtil.isNotBlank(startDateStr) ? LocalDate.parse(startDateStr) : null, StrUtil.isNotBlank(endDateStr) ? LocalDate.parse(cendDateStr) : null) .groupBy(OrderModel::getMerNo));

虽然看起来还是不够优雅,但是我觉得已经是最优的方案了,如果有更好的写法,可以在评论区留言。 写法绝对是本人自己思考后写出来的,因为在网上搜了一个多小时,也没看到什么更优雅的写法,如果本篇文章对你有帮助的话,就动动点击下方大拇指,给个免费的赞,不然我真的会谢。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lsinopec@gmail.com举报,一经查实,本站将立刻删除。

上一篇 没有了

下一篇没有了