Mybatis plus之LambdaQueryWrapper使用sum函数求和,你会用吗
MyBatis-Plus 实现按字段求和查询的通用方案
SUM 函数。通常,开发者可能会选择在 XML 文件中编写 SQL 来解决这个问题,但本文将提供一种更便捷的方式,通过封装通用方法,直接在 Java 代码中调用实现求和查询。环境版本说明
- MyBatis-Plus:3.4.0
- Spring Boot:2.7.17
- MySQL:8.0
实现步骤
1. 定义实体类
OutputInvoice 实体类的代码:package com.zxh.entity; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import java.math.BigDecimal; // 实体类,用于表示查询结果
@Data
@TableName("output_invoice")
public class OutputInvoice {
//开票金额
private BigDecimal amount;
//税额
private BigDecimal tax;
//发票状态,1'已开票',2'已作废'
private String status;
//发票号码
private String invoiceNo;
//发票代码
private String invoiceCode;
}
2. 创建数据库表并插入示例数据
-- 创建 output_invoice 表
CREATE TABLE output_invoice (
-- 开票金额,使用 DECIMAL 类型存储精确的数值,10 为总位数,2 为小数位数
amount DECIMAL(10, 2) COMMENT '开票金额',
-- 税额,使用 DECIMAL 类型存储精确的数值,10 为总位数,2 为小数位数
tax DECIMAL(10, 2) COMMENT '税额',
-- 发票状态,1 表示已开票,2 表示已作废
status VARCHAR(2) COMMENT '发票状态,1已开票,2已作废',
-- 发票号码,用于唯一标识一张发票
invoiceNo VARCHAR(20) COMMENT '发票号码',
-- 发票代码,用于标识发票的类别等信息
invoiceCode VARCHAR(20) COMMENT '发票代码'
) COMMENT '销项发票信息表'; -- 插入示例数据
INSERT INTO output_invoice (amount, tax, status, invoiceNo, invoiceCode)
VALUES
(1000.00, 130.00, '1', '12345678', '00000001'),
(2000.50, 260.07, '1', '87654321', '00000002'),
(500.20, 65.03, '2', '98765432', '00000003');
3. 封装通用查询工具类
QueryUtils 工具类,该类封装了 selectSumBySQL 方法,用于执行求和查询。以下是工具类的代码:
package com.zxh.util; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function; import static cn.hutool.core.collection.CollectionUtil.isNotEmpty; /**
* 查询工具类,提供通用的求和查询方法
*/
@Slf4j
public class QueryUtils { /**
* 执行按字段求和的查询
* @param lambdaQueryWrapper Lambda 查询条件包装器
* @param sumSQL 求和的 SQL 语句
* @param tClass 实体类的 Class 对象
* @param queryExecutor 查询执行器,用于执行查询操作
* @param <T> 实体类的泛型类型
* @return 查询结果的实体类对象
*/
public <T> T selectSumBySQL(LambdaQueryWrapper<T> lambdaQueryWrapper, String sumSQL, Class<T> tClass, Function<QueryWrapper<T>, List<Map<String, Object>>> queryExecutor) {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
// 使用 sum 求和
queryWrapper.select(sumSQL); // 获取 LambdaQueryWrapper 的 SQL 片段和参数映射
String sqlSegment = lambdaQueryWrapper.getCustomSqlSegment();
Map<String, Object> paramNameValuePairs = lambdaQueryWrapper.getParamNameValuePairs(); log.info("执行 sum 查询 lambdaQueryWrapper SQL: {}", sqlSegment);
log.info("执行 sum 查询 lambdaQueryWrapper 参数: {}", paramNameValuePairs); // 拼接 SQL 片段
if (sqlSegment != null && !sqlSegment.isEmpty()) {
if (sqlSegment.trim().toLowerCase().startsWith("where")) {
sqlSegment = sqlSegment.substring(5).trim();
}
queryWrapper.last("WHERE " + sqlSegment);
} // 直接使用 LambdaQueryWrapper 的参数映射
queryWrapper.getParamNameValuePairs().putAll(paramNameValuePairs); // 打印最终的 QueryWrapper 信息
log.info("执行 sum 查询 QueryWrapper SQL: {}", queryWrapper.getCustomSqlSegment());
log.info("执行 sum 查询 QueryWrapper 参数: {}", queryWrapper.getParamNameValuePairs()); // 使用执行器进行查询
List<Map<String, Object>> mapList = queryExecutor.apply(queryWrapper);
if (isNotEmpty(mapList)) {
Map<String, Object> sumMap = mapList.get(0);
if (sumMap != null) {
try {
// 创建实体类的实例
T result = tClass.getDeclaredConstructor().newInstance();
// 遍历实体类的字段
for (Field field : tClass.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = sumMap.get(fieldName);
if (value != null) {
if (field.getType() == BigDecimal.class) {
value = new BigDecimal(value.toString());
}
// 将查询结果设置到实体类的对应字段中
field.set(result, value);
}
}
return result;
} catch (Exception e) {
log.error("查询求和方法异常:", e);
throw new RuntimeException(e);
}
}
}
return null;
}
}
4.调用测试
QueryUtils 工具类的功能。以下是测试代码:package com.zxh; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zxh.dao.OutputInvoiceMapper;
import com.zxh.entity.OutputInvoice;
import com.zxh.util.QueryUtils;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; @SpringBootTest
@Slf4j
class SpringbootDemoApplicationTests { @Resource
private OutputInvoiceMapper outputInvoiceMapper; @Test
public void test() {
QueryUtils queryUtils = new QueryUtils();
LambdaQueryWrapper<OutputInvoice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(OutputInvoice::getStatus, "1");
//汇总的sql
String sumSQL = "SUM(amount) as amount,SUM(tax) as tax";
// 调用 selectSumBySQL 方法
OutputInvoice sumResult = queryUtils.selectSumBySQL(
lambdaQueryWrapper,
sumSQL,
OutputInvoice.class,
outputInvoiceMapper::selectMaps);
// 验证结果
if (sumResult != null) {
System.out.println("查询结果: " + sumResult);
} else {
System.out.println("未查询到结果");
} } }
打印结果

代码解释
LambdaQueryWrapper 本身不支持 SUM 函数,我们借助 QueryWrapper 传入自定义的求和 SQL 语句。将两者结合的原因是,LambdaQueryWrapper 在构建查询条件时具有优势,只需指定对象的字段名即可。通过这种方式,我们可以在不使用 XML 文件的情况下,直接在 Java 代码中实现按字段求和的查询功能。Mybatis plus之LambdaQueryWrapper使用sum函数求和,你会用吗的更多相关文章
- MyBatis的foreach标签与SUM函数同时使用
最近在项目中遇到一个,需要根据传入的存有id的list,计算值,再起别名 <if test="channelList != null and channelList.size()> ...
- mysql 语句中 sum函数求和 null 变 0
https://blog.csdn.net/Z_passionate/article/details/83821039
- 水晶报表分组,统计,求和,sum()函数使用
--Sum()函数统计的是明细所有的和 Sum(字段名) --根据分组字段统计的和 Sum ({xh_Getdinggoudan;1.Djine} ,{xh_Getdinggoudan;1.Ddgda ...
- 在mybatis中使用sum函数返回对象为Null
首先大家看一下我的XML中的SQL .DAO 和实体对象 XML DAO PO 乍一看 没毛病. 但是在Mybatis中使用sum函数,如果返回值是0(就是你在Navicat中运行的的sql正常,结 ...
- Access数据库中Sum函数返回空值(Null)时如何设置为0
在完成一个Access表中数据统计时,需要统计指定字段的和,使用到了Sum函数,但统计时发现,指定条件查询统计时有可能返回空值(Null),导致对应字段显示为空白,正常应显示为0.基本思路是在获取记录 ...
- 关于SQL语句中SUM函数返回NULL的解决办法
SUM 是SQL语句中的标准求和函数,如果没有符合条件的记录,那么SUM函数会返回NULL. 但多数情况下,我们希望如果没有符合条件记录的情况下,我们希望它返回0,而不是NULL,那么我们可以使用例如 ...
- 如何给列表降维?sum()函数的妙用
上个月,学习群里的 S 同学问了个题目,大意可理解为列表降维 ,例子如下: oldlist = [[1, 2, 3], [4, 5]] # 想得到结果:newlist = [1, 2, 3, 4, 5 ...
- Python sum() 函数
Python sum() 函数 Python 内置函数 描述 sum() 方法对系列进行求和计算. 语法 以下是 sum() 方法的语法: sum(iterable[, start]) 参数 ite ...
- python中numpy.sum()函数
讲解清晰,转载自:https://blog.csdn.net/rifengxxc/article/details/75008427 众所周知,sum不传参的时候,是所有元素的总和.这里就不说了. 1 ...
- sql 中sum函数返回null的解决方案
SUM 是SQL语句中的标准求和函数,如果没有符合条件的记录,那么SUM函数会返回NULL. 但多数情况下,我们希望如果没有符合条件记录的情况下,我们希望它返回0,而不是NULL,那么我们可以使用例如 ...
随机推荐
- Ansys
简介 Ansys 使用 explore (爆炸)功能分离 装配体,然后自己手动生成接触面 采用摩擦 image
- POLIR-Organization-Gov.: 国家网信办 和 公安部 的 "人脸识别技术应用安全管理办法"
人脸识别技术应用安全管理办法 2025年03月21日 17:00,来源:中国网信网 国家互联网信息办公室 中华人民共和国公安部 令 第19号 <人脸识别技术应用安全管理办法>已经2024年 ...
- POLIR-Society-Organization-Management-{CNO5R 立场+金钱价值观+目标需求+服务产品+管理控制}- 执行:Life+Question+Blueprint{GoalSetting/DecisionMaking/Plan/Milestones/DailyActionItems}
Customer SATISFACTION: 我们最终为"何种目标人群"服务,这是根本立场问题. 不卑不亢, 不图暴利与不确定的权利, 只赚可靠放心的稳钱. 聚焦目标,谁最终自主为 ...
- tauri学习(7)-事件(event)
接上节继续,今天来研究tauri的事件(event),假设老板提了个需求,希望能实时监控cpu.内存等性能指标,你会怎么做? 思路1: 后端Rust暴露1个command,前端js不停去轮询(参考前文 ...
- 基础篇:6.5)形位公差-标注 Mark
本章目的:了解形位公差是如何标注的,及其意义: 1.形位公差框格 Feature Control Frames 2.被测要素的标注(两国标准不同) 2.1 中国GB标准 - 形位公差框格通过用带箭头的 ...
- win10纯净版用Edge浏览器内存占用高的问题
有深度技术的小伙伴都很习惯的使用win10纯净版自带的Edge浏览器,但Edge浏览器经常会出现占用内存过高,导致了电脑运行缓慢的问题.接下来,深度系统小编就来分享具体的处理方法,大家一起来看看吧. ...
- 2023年4月最新全国省市区县和乡镇街道行政区划矢量边界坐标经纬度地图数据 shp geojson json
发现个可以免费下载全国 geojson 数据的网站,推荐一下.支持全国.省级.市级.区/县级.街道/乡镇级以及各级的联动数据,支持导入矢量地图渲染框架中使用,例如:D3.Echarts等 geojso ...
- C# 蓝牙开发你必须知道
无线,无网络环境上位机与下位机连接方式比较常见的就是蓝牙与串口,这里记录回顾一下这段时间蓝牙开发方面的记录. 蓝牙分为BLE蓝牙与经典蓝牙,两者主频都是2.4GHz,传输距离,范围,吞吐量可以自己 ...
- 【数据库基石】聚簇索引 vs 非聚簇索引:结构图解、性能差异与最佳实践
深入解析:聚簇索引 vs 非聚簇索引的核心区别与工作原理 数据库索引设计的必修课 一.核心区别概览 通过对比表快速掌握核心差异: 特性 聚簇索引 非聚簇索引 关键影响 索引数量 每表仅1个 每表可多个 ...
- 重生之 CF2126G2. Big Wins! (hard version)
$$ 高考结束了,前退役 \text{Oie} 要开始 \text{Ta} 的 \text{ACM} 生活了. $$ 前置:一个区间的 \(med \geq x\) 等价于若将 \(a_i \geq ...