MybatisPlus中Sum函数使用方法及示例代码详解

原创 2025-06-12 10:24:45编程技术
569

在MyBatis-Plus中,Sum函数是用于实现聚合查询的核心功能之一,常用于统计数值型字段的总和(如订单金额、用户积分等)。本文ZHANID工具网将详细讲解Sum函数的使用方法,结合QueryWrapperLambdaQueryWrapper两种方式,并提供完整示例代码。

一、Sum函数基础用法

1. 使用QueryWrapper实现Sum查询

场景:统计order表中所有订单的amount字段总和。

代码示例

// 创建QueryWrapper
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.select("SUM(amount) as totalAmount");

// 执行查询
List<Map<String, Object>> result = orderMapper.selectMaps(queryWrapper);

// 解析结果
BigDecimal totalAmount = (BigDecimal) result.get(0).get("totalAmount");
System.out.println("总金额: " + totalAmount);

关键点

  • select("SUM(amount) as totalAmount"):指定聚合函数并设置别名。

  • selectMaps():返回List<Map>,需通过别名提取结果。

  • 默认返回BigDecimal类型,避免精度丢失。

2. 使用LambdaQueryWrapper实现Sum查询

场景:统计满足条件的订单总金额(如状态为已支付的订单)。

代码示例

LambdaQueryWrapper<Order> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(Order::getAmount, Order::getStatus)
            .eq(Order::getStatus, "PAID")
            .select("SUM(amount) as totalAmount");

List<Map<String, Object>> result = orderMapper.selectMaps(lambdaWrapper);
BigDecimal paidTotal = (BigDecimal) result.get(0).get("totalAmount");

优势

  • 使用Lambda表达式避免硬编码字段名,提升代码可读性。

  • 支持链式调用,可组合多个查询条件。

二、Sum函数结合分组(GROUP BY)

场景:按用户ID统计订单总金额,并筛选总金额大于1000的用户。

代码示例

LambdaQueryWrapper<Order> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(Order::getUserId, "SUM(amount) as totalAmount")
            .groupBy(Order::getUserId)
            .having("SUM(amount) > {0}", 1000);

List<Map<String, Object>> result = orderMapper.selectMaps(lambdaWrapper);
result.forEach(item -> {
    Long userId = (Long) item.get("userId");
    BigDecimal total = (BigDecimal) item.get("totalAmount");
    System.out.println("用户" + userId + "总金额: " + total);
});

关键点

  • groupBy():指定分组字段。

  • having():过滤分组后的结果(支持参数占位符{0})。

三、Sum函数结合排序(ORDER BY)

场景:统计各商品类别的销售额,并按总销售额降序排列。

代码示例

LambdaQueryWrapper<Product> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(Product::getCategoryId, "SUM(price * stock) as totalSales")
            .groupBy(Product::getCategoryId)
            .orderByDesc("totalSales");

List<Map<String, Object>> result = productMapper.selectMaps(lambdaWrapper);
result.forEach(item -> {
    Long categoryId = (Long) item.get("categoryId");
    BigDecimal sales = (BigDecimal) item.get("totalSales");
    System.out.println("分类" + categoryId + "销售额: " + sales);
});

说明

  • orderByDesc("totalSales"):按聚合结果排序(需使用别名)。

四、Service层封装示例

推荐做法:在Service层封装通用聚合查询方法。

代码示例

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;

    public BigDecimal calculateTotalAmount(String status) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getAmount)
               .eq(Order::getStatus, status)
               .select("SUM(amount) as totalAmount");
        
        List<Map<String, Object>> result = orderMapper.selectMaps(wrapper);
        if (result.isEmpty() || result.get(0).get("totalAmount") == null) {
            return BigDecimal.ZERO;
        }
        return (BigDecimal) result.get(0).get("totalAmount");
    }
}

调用示例

// 统计所有已支付订单总金额
BigDecimal total = orderService.calculateTotalAmount("PAID");
System.out.println("已支付总金额: " + total);

MybatisPlus.webp

五、高级用法:多字段聚合查询

场景:同时统计订单数、总金额和平均金额。

代码示例

LambdaQueryWrapper<Order> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(
    "COUNT(*) as orderCount",
    "SUM(amount) as totalAmount",
    "AVG(amount) as avgAmount"
)
.eq(Order::getStatus, "PAID");

List<Map<String, Object>> result = orderMapper.selectMaps(lambdaWrapper);
Map<String, Object> stats = result.get(0);
System.out.println("订单数: " + stats.get("orderCount"));
System.out.println("总金额: " + stats.get("totalAmount"));
System.out.println("平均金额: " + stats.get("avgAmount"));

六、注意事项

  1. 字段别名
    使用select("SUM(amount) as totalAmount")必须指定别名,否则无法通过Map键获取结果。

  2. 空值处理
    当查询无结果时,result.get(0)可能为null,需做空指针判断。

  3. 类型安全
    返回的数值类型默认为BigDecimal,避免使用Double导致精度丢失。

  4. 性能优化
    对大数据量表使用聚合查询时,建议添加必要的索引(如分组字段、过滤字段)。

七、完整示例代码结构

src/
├── main/
│   ├── java/
│   │   └── com/example/
│   │       ├── entity/Order.java
│   │       ├── mapper/OrderMapper.java
│   │       ├── service/OrderService.java
│   │       └── controller/OrderController.java

Order实体类

@Data
@TableName("t_order")
public class Order {
    private Long id;
    private Long userId;
    private BigDecimal amount;
    private String status;
    private Date createTime;
}

OrderMapper接口

public interface OrderMapper extends BaseMapper<Order> {
    // 继承BaseMapper即可,无需额外方法
}

八、总结

MyBatis-Plus通过QueryWrapperLambdaQueryWrapper提供了灵活的Sum函数使用方式,核心步骤包括:

  1. 使用select()指定聚合函数及别名。

  2. 通过groupBy()/having()/orderBy()实现复杂统计。

  3. 在Service层封装通用方法提升复用性。

合理使用聚合查询可大幅提升数据统计效率,结合索引优化能应对百万级数据量的统计需求。实际开发中建议优先使用LambdaQueryWrapper以规避字段名硬编码风险。

MybatisPlus Sum
THE END
战地网
频繁记录吧,生活的本意是开心

相关推荐

电脑开机提示“CMOS checksum error”的原因及解决方法详解
在日常使用计算机的过程中,偶尔会遇到一些硬件相关的开机错误提示,其中之一就是“CMOS checksum error”。这一提示通常出现在电脑启动的早期阶段,意味着主板 BIOS 无法正确...
2025-09-10 电脑知识
560

QueryWrapper入门教程:从零开始构建MyBatis-Plus查询条件
MyBatis-Plus QueryWrapper 是构建动态查询条件的核心类之一,能够帮助开发者高效、安全地拼接SQL查询语句。本文ZHANID工具网将从零开始,详细介绍 QueryWrapper 的基本用法,...
2025-08-29 编程技术
430

为什么你的SUMIFS总不对?这3个参数设置是关键!
在Excel中,SUMIFS函数是处理多条件求和的“瑞士军刀”,但你是否遇到过明明公式逻辑正确,结果却总显示#VALUE!或计算错误?本文ZHANID工具网将深入剖析SUMIFS函数的3个核心参...
2025-05-07 电脑知识
1345

mybatis和mybatisplus的区别是什么?它们可以共存吗?
在Java持久层框架领域,MyBatis与MyBatis-Plus的关系常引发开发者讨论。本文ZHANID工具网将从技术演进、功能特性、使用差异及共存方案等维度展开分析,帮助开发者明确两者定位...
2025-04-28 编程技术
977

Excel中SUMPRODUCT函数的使用方法及实例详解
SUMPRODUCT函数以其灵活性和多功能性,在数据汇总、条件计算及数组运算等方面展现出独特的优势。本文ZHANID工具网将深入解析eXcel中SUMPRODUCT函数的使用方法,并通过具体实例...
2025-03-31 电脑知识
1059

Excel中sumifs函数的使用方法及实例详解:多条件求和竟能如此简单?
在Excel的数据处理中,求和是一个常见的操作。然而,当需要基于多个条件对数据进行求和时,传统的SUM函数就显得力不从心了。这时,SUMIFS函数便应运而生,它以其强大的多条件...
2025-03-28 电脑知识
1209