[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"solution-scenes-menu":3,"tech-detail-2345":4},true,{"id":5,"title":6,"content":7,"picUrl":8,"tagIds":9,"keyWords":10,"htmlDescribe":11,"htmlUrl":12,"gmtCreate":13,"gmtModified":13,"articleInfoId":14},"2345","美畅物联丨Java后端开发中使用 MyBatis-Plus 进行分页查询时的排序问题及解决方法","\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F11\u002F15\u002Ff0a6bd0e-5cfc-4172-aaf1-bf7f1f49d16a.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">在 Java 后端开发中，分页查询是高频使用的功能。尤其在数据量较大的情况下，分页查询能够有效地提高性能。然而，若在分页查询中没有添加排序条件，可能会产生一些数据重复或遗漏的问题。这种情况在数据有频繁插入、更新的场景下尤为明显。本文将分析 MyBatis-Plus 在分页查询中未使用排序可能引发的问题，并提供合理的解决方法，帮助开发人员构建稳定可靠的分页查询。\u003C\u002Fp>\u003Ch1 style=\"text-align:left;line-height:2\">\u003Cstrong>问题分析\u003C\u002Fstrong>\u003C\u002Fh1>\u003Cp style=\"text-align:center;line-height:2\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F11\u002F15\u002F2dd69785-5deb-46a7-9abf-44c46229bbfc.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">在 MyBatis-Plus 的分页查询中，若没有指定排序条件，数据库会根据默认的排序方式来返回数据。然而，这种默认方式在数据表有并发更新的情况下，会导致分页结果不稳定，容易出现以下问题：\u003C\u002Fp>\u003Cp style=\"text-align:left;line-height:2\">\u003Cspan style=\"font-size:16px\">\u003Cstrong>1. 数据重复：\u003C\u002Fstrong>\u003C\u002Fspan>同一条数据会在不同页出现多次。\u003C\u002Fp>\u003Cp style=\"text-align:left;line-height:2\">\u003Cspan style=\"font-size:16px\">\u003Cstrong>2. 数据遗漏：\u003C\u002Fstrong>\u003C\u002Fspan>由于数据插入或删除，部分数据可能在翻页时无法展示。\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">例如，若表 device_channel 中的数据量较大且存在频繁写操作，查询某一页的数据可能会因为数据的变动而导致返回的数据不稳定，这会给业务逻辑带来不准确的结果。因此，为了确保分页的准确性，建议在分页查询中添加排序条件。\u003C\u002Fp>\u003Ch1 style=\"text-align:left;line-height:2\">\u003Cstrong>解决方法\u003C\u002Fstrong>\u003C\u002Fh1>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">解决该问题的最佳方案是通过唯一字段进行排序，如时间戳字段或主键字段，以确保数据顺序的稳定性。下面将提供两种具体实现方法，分别基于 MyBatis-Plus 的 QueryWrapper 和 LambdaQueryWrapper，并结合排序条件来避免数据的重复或遗漏。\u003C\u002Fp>\u003Ch2 style=\"text-align:left;line-height:2\">\u003Cstrong>1. 使用 QueryWrapper 配合排序进行分页查询\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">使用 QueryWrapper 可以灵活地构建查询条件，并通过 Page 对象中的 setOrders() 方法指定排序规则。以下代码展示了基于 QueryWrapper 的分页查询实现：\u003C\u002Fp>\u003Cpre>\u003Ccode>import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.baomidou.mybatisplus.core.metadata.OrderItem;\n\npublic ResultEntity channelList(Long authOrderId, Integer page, Integer limit) {\n    \u002F\u002F 构造查询条件\n    QueryWrapper&lt;DeviceChannel&gt; queryWrapper = new QueryWrapper&lt;&gt;();\n    queryWrapper.eq(\"auth_order_id\", authOrderId)\n    .eq(\"is_deleted\", 0);\n    \u002F\u002F 设置分页参数并指定排序字段\n    Page&lt;DeviceChannel&gt; pageParam = new Page&lt;&gt;(page, limit);\n    pageParam.setOrders(Arrays.asList(\n        OrderItem.desc(\"gmt_create\"), \u002F\u002F 按创建时间降序排列\n        OrderItem.asc(\"device_channel_id\") \u002F\u002F 按主键升序排列，确保排序唯一性\n    ));\nreturn ResultEntity.page(deviceChannelService.page(pageParam, queryWrapper));\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:left;line-height:2\">在此实现中，使用了 gmt_create 字段按降序排序，同时按主键 device_channel_id 升序排序，以保证分页查询结果的顺序性和唯一性。这种组合排序在 gmt_create 相同的情况下可以避免重复数据的出现。\u003C\u002Fp>\u003Ch2 style=\"text-align:justify;line-height:2\">\u003Cstrong>2、使用 LambdaQueryWrapper 配合排序进行分页查询\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-indent:2em;text-align:justify;line-height:2\">LambdaQueryWrapper 是 MyBatis-Plus 提供的一种更安全的方式，用于避免写错字段名称。以下是基于 LambdaQueryWrapper 的分页查询示例：\u003C\u002Fp>\u003Cpre>\u003Ccode> import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\n import com.baomidou.mybatisplus.extension.plugins.pagination.Page;\n import com.baomidou.mybatisplus.core.metadata.OrderItem;\n\n public ResultEntity channelList(Long authOrderId, Integer page, Integer limit) {\n     \u002F\u002F 构造 LambdaQueryWrapper 查询条件\n     LambdaQueryWrapper&lt;DeviceChannel&gt; lambdaQueryWrapper = new LambdaQueryWrapper&lt;&gt;();\n     lambdaQueryWrapper.eq(DeviceChannel::getAuthOrderId, authOrderId)\n     .eq(DeviceChannel::getIsDeleted, 0);\n\n     \u002F\u002F 设置分页参数并指定排序字段\n     Page&lt;DeviceChannel&gt; pageParam = new Page&lt;&gt;(page, limit);\n     pageParam.setOrders(Arrays.asList(\n     OrderItem.desc(\"gmt_create\"), \u002F\u002F 按创建时间降序排列\n     OrderItem.asc(\"device_channel_id\") \u002F\u002F 按主键升序排列\n     ));\n     return ResultEntity.page(deviceChannelService.page(pageParam, lambdaQueryWrapper));\n }\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:justify;line-height:2\">在这段代码中，LambdaQueryWrapper 提供了基于 Java lambda 表达式的字段引用（如 DeviceChannel::getAuthOrderId），从而避免了手写字段名称带来的错误。同时，排序条件与上一个示例相同，仍然是 gmt_create 和 device_channel_id 的组合排序，以确保分页查询的顺序稳定性。\u003C\u002Fp>\u003Ch1 style=\"text-align:justify;line-height:2\">\u003Cstrong>总结\u003C\u002Fstrong>\u003C\u002Fh1>\u003Cp style=\"text-indent:2em;text-align:justify;line-height:2\">在使用 MyBatis-Plus 进行分页查询时，确保结果的顺序稳定非常重要。缺乏排序条件的分页查询会导致数据重复或遗漏的风险，特别是在存在频繁数据变动的场景下。本文提供了两种基于 MyBatis-Plus 的排序分页查询方案，即 QueryWrapper 和 LambdaQueryWrapper，它们不仅能提高代码的可读性，还能确保数据的稳定性和一致性。建议开发人员在分页查询中根据具体业务场景选择合适的排序字段，以确保分页查询结果的稳定性和准确性。\u003C\u002Fp>\u003Cp style=\"text-align:left;line-height:2\">————————————————\u003C\u002Fp>\u003Cp style=\"text-align:left;line-height:2\">\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">关注\u003C\u002Fspan>\u003Cspan style=\"color:rgb(66, 144, 247);background-color:rgb(255, 255, 255);font-size:16px\">\u003Cstrong>“美畅物联”\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">，了解更多视频汇聚及AIoT底座解决方案。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-align:justify;line-height:2\">\u003Cbr \u002F>\u003C\u002Fp>","https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F11\u002F15\u002F62d2b508-7208-44ec-8166-bbdb5f44ccb7.jpg","9","美畅，美畅物联，畅联，畅联云平台，视频监控云平台，云视频监控，视频云平台，视频开放平台，视频感知云，视频接入网关，AIoT综合接入网关，视频中台，物联网中台，无插件播放，H265播放，Ehome，ISUP， GB28181，GB35114，gat1400，JT808，JT1078","原创技术分享","http:\u002F\u002Fwww.24hlink.cn\u002Fweb-index\u002F6IL32M6.html","2024-11-15 15:59:11","787"]