Mybatis 查询列表,在需要对 order by 部分进行动态设置的时候,查询报错了:

Caused by: net.sf.jsqlparser.JSQLParserException: null
    at net.sf.jsqlparser.parser.CCJSqlParserUtil.parseStatements(CCJSqlParserUtil.java:154)
    at com.baomidou.mybatisplus.core.parser.AbstractJsqlParser.parser(AbstractJsqlParser.java:64)
    ... 93 common frames omitted
Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "?" "?"
    at line 95, column 24.

Was expecting one of:

    "&"
    ")"
    ","
    "::"
    "<<"
    ">>"
    "ASC"
    "DESC"
    "EXCEPT"
    "FOR"
    "INTERSECT"
    "MINUS"
    "NULLS"
    "ORDER"
    "UNION"
    "^"
    "|"

错误信息上面有 sql,但排序部分显示的是占位符,也不知道最后执行的 sql 存在什么问题。如果直接 order by id desc 是正常的,sql 测试发现,即使不传 order,也会默认使用 asc 正序排序,而不会报错。

百度了解到,#{} 用于预处理语句,而预处理语句中的占位符不能用于列名或表名。但我这边传递的也不是列名,而是 mysql 的排序关键词 ascdesc。提示使用 ${} 替换 #{} 可能会有 sql 注入风险。这边大概理解就是 ${} 是原样输出,所以存在风险,而 #{} 相当于占位符,会对变量值进行预处理,比如转义使其只能表示字符串。

使用 order by id ${order},成功!

实际开发中一定要对输入的参数增加一个值判断,只允许确定的值传入,不然就会有 sql 注入风险。