news 2026/4/18 7:10:52

MyBatis-Plus 多字段排序详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis-Plus 多字段排序详解

MyBatis-Plus 多字段排序详解

1.基本多字段排序

QueryWrapper 方式

java

// 多个字段排序:按年份降序,按状态升序,按创建时间降序 QueryWrapper<CapitalInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc("capital_year") // 第一排序:年份降序 .orderByAsc("capital_state") // 第二排序:状态升序 .orderByDesc("create_time"); // 第三排序:创建时间降序 List<CapitalInfo> list = capitalInfoMapper.selectList(queryWrapper);

LambdaQueryWrapper 方式

java

// Lambda方式多字段排序 LambdaQueryWrapper<CapitalInfo> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.orderByDesc(CapitalInfo::getCapitalYear) // 年份降序 .orderByAsc(CapitalInfo::getCapitalState) // 状态升序 .orderByDesc(CapitalInfo::getCreateTime); // 创建时间降序 List<CapitalInfo> list = capitalInfoMapper.selectList(lambdaWrapper);

2.高级排序方法

2.1orderBy()方法

java

// orderBy(boolean condition, boolean isAsc, R... columns) // condition: 是否应用排序,isAsc: 是否升序,columns: 排序字段 QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 动态条件排序 boolean needSort = true; boolean isAsc = false; // 降序 wrapper.orderBy(needSort, isAsc, "capital_year", "create_time"); // 等价于:ORDER BY capital_year DESC, create_time DESC // Lambda方式 LambdaQueryWrapper<CapitalInfo> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.orderBy(needSort, isAsc, CapitalInfo::getCapitalYear, CapitalInfo::getCreateTime);

2.2orderByAsc()orderByDesc()单个字段

java

QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 混合升降序 wrapper.orderByAsc("capital_state") // 状态升序 .orderByDesc("capital_year") // 年份降序 .orderByAsc("capital_type") // 类型升序 .orderByDesc("create_time"); // 创建时间降序 // 生成的SQL: ORDER BY capital_state ASC, capital_year DESC, // capital_type ASC, create_time DESC

2.3 多字段统一升降序

java

// 多个字段统一升序 QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); wrapper.orderByAsc(Arrays.asList("capital_year", "capital_state", "create_time")); // 等价于: ORDER BY capital_year ASC, capital_state ASC, create_time ASC // 多个字段统一降序 wrapper.orderByDesc(Arrays.asList("capital_year", "capital_state", "create_time")); // 等价于: ORDER BY capital_year DESC, capital_state DESC, create_time DESC // Lambda方式 LambdaQueryWrapper<CapitalInfo> lambdaWrapper = new LambdaQueryWrapper<>(); lambdaWrapper.orderByAsc(Arrays.asList( CapitalInfo::getCapitalYear, CapitalInfo::getCapitalState, CapitalInfo::getCreateTime ));

3.动态条件排序

3.1 根据参数动态排序

java

public List<CapitalInfo> queryWithDynamicSort(CapitalInfoQueryDTO queryDTO, String sortField, String sortOrder) { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 构建查询条件 if (StringUtils.isNotBlank(queryDTO.getCapitalName())) { wrapper.like("capital_name", queryDTO.getCapitalName()); } // 动态排序 if (StringUtils.isNotBlank(sortField)) { if ("asc".equalsIgnoreCase(sortOrder)) { wrapper.orderByAsc(sortField); } else { wrapper.orderByDesc(sortField); } } else { // 默认排序 wrapper.orderByDesc("create_time").orderByAsc("capital_state"); } return capitalInfoMapper.selectList(wrapper); }

3.2 多字段动态排序

java

public List<CapitalInfo> queryWithMultiSort(CapitalInfoQueryDTO queryDTO, List<SortItem> sortItems) { QueryWrapper<CapitalInfo> wrapper = buildQueryWrapper(queryDTO); // sortItems: [{"field":"capitalYear","order":"desc"}, // {"field":"capitalState","order":"asc"}] if (CollectionUtils.isNotEmpty(sortItems)) { for (SortItem item : sortItems) { if ("asc".equalsIgnoreCase(item.getOrder())) { wrapper.orderByAsc(item.getField()); } else if ("desc".equalsIgnoreCase(item.getOrder())) { wrapper.orderByDesc(item.getField()); } } } return capitalInfoMapper.selectList(wrapper); } // 排序项DTO @Data class SortItem { private String field; // 排序字段 private String order; // asc/desc }

4.复杂排序场景

4.1 条件排序

java

public List<CapitalInfo> queryWithConditionalSort(CapitalInfoQueryDTO queryDTO) { LambdaQueryWrapper<CapitalInfo> wrapper = new LambdaQueryWrapper<>(); // 根据资金状态决定排序规则 if (queryDTO.getCapitalState() != null && queryDTO.getCapitalState() == 1) { // 状态为1时:按年份降序,创建时间升序 wrapper.orderByDesc(CapitalInfo::getCapitalYear) .orderByAsc(CapitalInfo::getCreateTime); } else { // 其他状态:按类型升序,年份降序 wrapper.orderByAsc(CapitalInfo::getCapitalType) .orderByDesc(CapitalInfo::getCapitalYear); } return capitalInfoMapper.selectList(wrapper); }

4.2 自定义排序函数

java

// 使用 orderBySql 实现自定义排序 public List<CapitalInfo> queryWithCustomSort() { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 使用SQL函数排序 wrapper.orderByAsc("FIELD(capital_state, 2, 1, 3, 0)"); // 自定义顺序 wrapper.orderByDesc("LENGTH(capital_name)"); // 按名称长度排序 // 按条件排序:状态为1的排前面 wrapper.orderByDesc("CASE WHEN capital_state = 1 THEN 1 ELSE 0 END"); return capitalInfoMapper.selectList(wrapper); }

4.3 分组后排序

java

public List<CapitalInfo> queryWithGroupByAndSort() { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 分组统计并排序 wrapper.select("capital_type", "capital_source", "COUNT(*) as count") .groupBy("capital_type", "capital_source") .orderByDesc("count") // 按数量降序 .orderByAsc("capital_type"); // 按类型升序 return capitalInfoMapper.selectList(wrapper); }

5.分页查询中的排序

5.1 分页排序

java

public IPage<CapitalInfo> queryPageWithSort(CapitalInfoQueryDTO queryDTO, Integer pageNum, Integer pageSize) { Page<CapitalInfo> page = new Page<>(pageNum, pageSize); LambdaQueryWrapper<CapitalInfo> wrapper = new LambdaQueryWrapper<>(); // 构建查询条件 if (StringUtils.isNotBlank(queryDTO.getCapitalName())) { wrapper.like(CapitalInfo::getCapitalName, queryDTO.getCapitalName()); } // 排序条件 wrapper.orderByDesc(CapitalInfo::getCapitalYear) .orderByAsc(CapitalInfo::getCapitalState) .orderByDesc(CapitalInfo::getCreateTime); return capitalInfoMapper.selectPage(page, wrapper); }

5.2 分页参数包含排序

java

@Data public class PageQueryDTO { private Integer pageNum = 1; private Integer pageSize = 10; private List<SortItem> sortItems; // 排序字段列表 } public IPage<CapitalInfo> queryPage(PageQueryDTO pageQuery, CapitalInfoQueryDTO queryDTO) { Page<CapitalInfo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); LambdaQueryWrapper<CapitalInfo> wrapper = new LambdaQueryWrapper<>(); // 构建查询条件 buildQueryWrapper(wrapper, queryDTO); // 应用排序 applySort(wrapper, pageQuery.getSortItems()); return capitalInfoMapper.selectPage(page, wrapper); } private void applySort(LambdaQueryWrapper<CapitalInfo> wrapper, List<SortItem> sortItems) { if (CollectionUtils.isEmpty(sortItems)) { // 默认排序 wrapper.orderByDesc(CapitalInfo::getCreateTime); return; } for (SortItem item : sortItems) { switch (item.getField()) { case "capitalYear": applyOrder(wrapper, CapitalInfo::getCapitalYear, item.getOrder()); break; case "capitalState": applyOrder(wrapper, CapitalInfo::getCapitalState, item.getOrder()); break; case "createTime": applyOrder(wrapper, CapitalInfo::getCreateTime, item.getOrder()); break; // 其他字段... } } } private <T> void applyOrder(LambdaQueryWrapper<CapitalInfo> wrapper, SFunction<CapitalInfo, T> column, String order) { if ("asc".equalsIgnoreCase(order)) { wrapper.orderByAsc(column); } else { wrapper.orderByDesc(column); } }

6.性能优化建议

6.1 排序索引优化

java

// 为常用排序字段添加索引 public List<CapitalInfo> queryOptimized() { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 优先使用有索引的字段排序 wrapper.orderByAsc("id") // 主键索引,排序效率高 .orderByDesc("capital_year_indexed") // 有索引的字段 .orderByAsc("capital_state"); return capitalInfoMapper.selectList(wrapper); }

6.2 限制排序数据量

java

public List<CapitalInfo> queryWithLimit() { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 先筛选再排序,减少排序数据量 wrapper.eq("capital_state", 1) .orderByDesc("create_time") .last("LIMIT 1000"); // 限制结果集大小 return capitalInfoMapper.selectList(wrapper); }

6.3 避免文件排序

java

public List<CapitalInfo> queryAvoidFileSort() { QueryWrapper<CapitalInfo> wrapper = new QueryWrapper<>(); // 确保where条件中的字段和order by字段有复合索引 wrapper.eq("capital_year", 2024) .eq("capital_type", "A") .orderByAsc("capital_state") // 复合索引(capital_year, capital_type, capital_state) .orderByDesc("create_time"); return capitalInfoMapper.selectList(wrapper); }

7.最佳实践总结

java

@Service public class CapitalInfoService { public List<CapitalInfo> queryWithBestPractice(CapitalInfoQueryDTO queryDTO) { // 推荐使用Lambda方式 LambdaQueryWrapper<CapitalInfo> wrapper = new LambdaQueryWrapper<>(); // 1. 先构建查询条件 buildQueryConditions(wrapper, queryDTO); // 2. 应用排序规则(清晰明了) applySortRules(wrapper, queryDTO); // 3. 如果需要分页 // Page<CapitalInfo> page = new Page<>(pageNum, pageSize); // return capitalInfoMapper.selectPage(page, wrapper); return capitalInfoMapper.selectList(wrapper); } private void buildQueryConditions(LambdaQueryWrapper<CapitalInfo> wrapper, CapitalInfoQueryDTO queryDTO) { wrapper.eq(queryDTO.getCapitalState() != null, CapitalInfo::getCapitalState, queryDTO.getCapitalState()) .like(StringUtils.isNotBlank(queryDTO.getCapitalName()), CapitalInfo::getCapitalName, queryDTO.getCapitalName()); } private void applySortRules(LambdaQueryWrapper<CapitalInfo> wrapper, CapitalInfoQueryDTO queryDTO) { // 明确的排序优先级 wrapper.orderByDesc(CapitalInfo::getCapitalYear) // 第一优先级:年份 .orderByAsc(CapitalInfo::getCapitalState) // 第二优先级:状态 .orderByDesc(CapitalInfo::getCreateTime) // 第三优先级:创建时间 .orderByAsc(CapitalInfo::getId); // 最后:ID保证稳定性 } }

关键点总结:

  1. 优先使用LambdaQueryWrapper,类型安全且重构友好

  2. 排序字段应遵循业务逻辑优先级

  3. 考虑添加数据库索引优化排序性能

  4. 对于大表查询,先筛选再排序

  5. 复杂的排序逻辑可以封装为独立的方法

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:37:37

Qwen3-VL数据分析:图表生成应用指南

Qwen3-VL数据分析&#xff1a;图表生成应用指南 1. 引言&#xff1a;Qwen3-VL-WEBUI 的实践价值 在当前多模态大模型快速演进的背景下&#xff0c;Qwen3-VL-WEBUI 作为阿里开源的交互式视觉语言模型前端工具&#xff0c;为开发者和数据分析师提供了一个低门槛、高效率的图表生…

作者头像 李华
网站建设 2026/4/18 8:35:45

Qwen3-VL 2D/3D感知:空间关系理解应用指南

Qwen3-VL 2D/3D感知&#xff1a;空间关系理解应用指南 1. 引言&#xff1a;为何需要空间感知的视觉语言模型 随着多模态AI在智能助手、机器人控制、AR/VR和自动化测试等场景中的广泛应用&#xff0c;仅能“看懂图像”的模型已无法满足复杂任务需求。真实世界中的交互不仅依赖…

作者头像 李华
网站建设 2026/4/18 11:56:21

窗口标签管理神器:WindowTabs让你的桌面焕然一新

窗口标签管理神器&#xff1a;WindowTabs让你的桌面焕然一新 【免费下载链接】WindowTabs A utility that brings browser-style tabbed window management to the desktop. 项目地址: https://gitcode.com/gh_mirrors/win/WindowTabs 还在为桌面上密密麻麻的窗口感到头…

作者头像 李华
网站建设 2026/4/18 11:00:57

AI如何帮你选择最佳杀毒软件?智能推荐系统解析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个AI杀毒软件推荐系统&#xff0c;要求&#xff1a;1. 集成主流杀毒软件API获取实时数据 2. 使用机器学习分析用户设备配置和使用习惯 3. 建立评分模型评估各软件防护能力 4…

作者头像 李华
网站建设 2026/4/18 5:42:24

酒店客房管理|基于Python +vue酒店客房管理系统(源码+数据库+文档)

酒店客房管理系统 目录 基于PythonDjango酒店客房管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于PythonDjango酒店客房管理系统 一、前言 博主介绍&#x…

作者头像 李华
网站建设 2026/4/18 10:48:25

对比评测:Instant Client vs 完整版Oracle客户端的效率差异

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个性能对比测试工具&#xff0c;功能&#xff1a;1. 自动安装Instant Client和完整客户端 2. 执行相同的100条SQL查询 3. 记录内存占用、CPU使用率和执行时间 4. 生成可视化…

作者头像 李华