MyBatis-Plus 中 SQL 注释引发的诡异解析异常:failed to concat orderBy from IPage

项目场景:

在开发或运行使用 MyBatis-Plus 分页功能的项目时,控制台突然抛出以下异常:

[http-nio-8082-exec-7] c.b.m.e.p.i.PaginationInnerInterceptor   failed to concat orderBy from IPage, exception:
java.util.concurrent.ExecutionException: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "group" "GROUP"
    at line 18, column 9.

Was expecting:
    <EOF>

问题排查

该异常直接指向 SQL 语法错误,且与分页时的 ORDER BY 拼接有关。通常需要检查:

  1. 分页查询的 Page 对象是否设置了正确的排序字段?
  2. 被分页的 SQL 语句本身语法是否正确?特别是 ORDER BY 子句附近。

根本原因分析

经过汗流浃背的排查,发现问题并非出现在 Page 对象的排序设置上,也不是 ORDER BY 子句本身的语法错误。

真正的罪魁祸首是:MyBatis-Plus 映射文件 (XXXMapper.xml) 中的 SQL 语句注释方式!


场景描述:

在一个较长的、包含 GROUP BY 子句的 SQL 语句中间,使用 XML 注释 (< !-- … -->) 注释掉了一段代码。

被注释掉的代码块恰好位于 GROUP BY 关键字之前或之中。

例如,原始有效的 SQL 结构可能是:

SELECT ... FROM ... WHERE ...
-- 这里被注释掉了一大段逻辑 (例如 JOIN 或 WHERE 条件)
GROUP BY ... -- 第18行附近
ORDER BY ...

在本案例中,注释导致了 GROUP BY 关键字直接暴露在了 SQL 语句中一个语法解析器无法理解的位置(例如,紧跟在某个未结束的表达式或子句之后,或者出现在 ORDER BY 应该出现的位置之前)。这使得 MyBatis-Plus 的分页拦截器在尝试追加 ORDER BY 时,整个 SQL 的语法结构已经因为之前的注释而被破坏,最终引发了 jsqlparser 在解析拼接后的 SQL 时遇到的 GROUP 关键字异常。


错误示例 (注释导致结构破坏):

<select id="selectComplexData" resultType="...">
    SELECT col1, col2, SUM(col3) AS total
    FROM main_table
    <!-- 原计划注释掉这个JOIN和相关条件,但注释位置不当 -->
    <!--
    JOIN other_table ON main_table.id = other_table.ref_id
    WHERE other_table.status = 'ACTIVE'
    AND some_condition = true
    -->
    GROUP BY col1, col2 -- 第18行:解析器期望前面有完整的FROM/JOIN/WHERE结构,但注释导致结构缺失
    ORDER BY col1 ASC
</select>

解决方案:

彻底删除无用代码: 将 XML 映射文件中被注释掉的、不再需要的 SQL 片段完全删除。这是最安全、最推荐的做法,避免未来维护者踩坑。

删除掉 XML 文件中导致 SQL 语法结构破坏的注释代码块后(或者将注释的sql挪到最后),SQL 语句恢复完整的、正确的语法结构。MyBatis-Plus 的分页拦截器 (PaginationInnerInterceptor) 能够正常地在原始 SQL 后追加 ORDER BY 子句,jsqlparser 也能正确解析拼接后的完整 SQL,异常消失,分页功能恢复正常。

经验总结:

  1. 警惕 XML 注释对 SQL 结构的影响: MyBatis XML 中的注释 (< !-- … -->)会物理移除注释内容。如果注释掉的是连接 SQL 关键部分的代码,极易导致剩余 SQL语法错误。这种错误往往比较隐蔽,因为注释掉的代码本身不执行,但会影响剩下的“可见”代码的结构。
  2. 清理无用代码: 长期不用的、注释掉的代码应及时清理,减少干扰和潜在风险。
  3. 理解分页拦截器的工作机制: MyBatis-Plus 的分页是通过拦截器修改原始 SQL 实现的。任何导致原始 SQL语法结构异常的因素(如本案例的注释破坏),都可能在拦截器拼接 ORDER BY 或 LIMIT 时暴露出来。
mybatis-plus 是基于 mybatis 的增强工具,提供了很多方便实用的功能,其中包括分页查询。分页查询通常用于处理海量数据时,对数据进行分页展示,以优化系统性能。 使用 mybatis-plus 进行分页查询需要注意以下几点: 1. 在 mapper 接口中定义方法时需要使用 IPage<T> 类型的参数,其中 T 为实体类。 2. 在 service 层调用 mapper 中的分页查询方法时,需要传入当前页数和每页显示的数量,可以通过 Page<T> 对象来实现。 3. 在 mapper 映射文件中使用 select 标签进行查询,需要按照 mybatis-plus 提供的语法结构来书写,主要包括表名、查询条件、分页条件等。 例如,以下是使用 mybatis-plus 进行分页查询的一个示例: 在 mapper 中定义方法: ``` public interface UserMapper extends BaseMapper<User> { IPage<User> selectUserByPage(Page<?> page, @Param("username") String username); } ``` 在 service 中实现分页查询: ``` @Override public IPage<User> getUserByPage(int pageNum, int pageSize, String username) { // 创建分页对象 Page<User> page = new Page<>(pageNum, pageSize); // 调用 mapper 方法进行分页查询 return userMapper.selectUserByPage(page, username); } ``` 在 mapper 映射文件中编写查询语句: ``` <select id="selectUserByPage" resultMap="userResultMap"> select * from user <where> <if test="username != null and username != ''"> and username like concat('%', #{username}, '%') </if> </where> order by id desc </select> ``` 通过以上步骤,就可以实现在 mybatis-plus 中进行分页查询并展示数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值