MyBatis XML特殊符号转义终极指南:告别解析错误,提升代码质量!
在MyBatis XML映射文件中,特殊符号如`<`、`>`、`&`等常常引发解析错误。本文将为你深入剖析两种核心转义方案:XML实体转义符与CDATA区块。我们将详细阐述它们的适用场景、优缺点,并提供实战建议,帮助你根据SQL复杂度灵活选择,确保XML文件正确解析,告别繁琐的转义工作,全面提升代码可维护性与团队开发效率。
支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道
2026-05-24 19:49:41 MyBatis 动态SQL SQL注入 空格缺失
最近线上日志突然开始报SQL语法错误,定位到一条排序查询,拼出来的SQL长这样:
ORDER BY columnNamedesc
很明显,字段名和排序方向之间没了空格。Mapper里是这么写的:
<if test="param.column != null and param.column != '' and param.sort != null and param.sort != ''">
ORDER BY ${param.column}${param.sort}
</if>
$ 占位符是直接往SQL里塞字符串,完全不会自动补空格,所以只要 column 和 sort 两个变量贴在一起,拼出来的就是 ORDER BY columnNamedesc 这种畸形语句。
手动加个空格就能解决:
ORDER BY ${param.column} ${param.sort}
不过这种写法依赖每个开发都记得留空格,时间长了或者别人改代码,很容易再次踩坑。后来我改用 trim 标签把 ORDER BY 前缀单独抽出来,让拼接更明确:
<if test="param.column != null and param.column != '' and param.sort != null and param.sort != ''">
<trim prefix="ORDER BY" suffixOverrides=",">
${param.column} ${param.sort}
</trim>
</if>
这里 suffixOverrides="," 虽然在这个单字段排序场景用不到,但如果是多字段排序用逗号拼接的场景,这个属性会自动去掉末尾多余的逗号,保留着也不碍事。
上面这些只解决了空格问题,$ 占位符本身还有SQL注入风险。
如果 param.column 或 param.sort 的值来自前端,有人可能传一个 "1; DROP TABLE..." 进来。所以在进Mapper之前必须做一层校验。我一般会在Service层加个白名单检查:
private boolean isValidSortParam(String column, String sort) {
List<String> allowedColumns = Arrays.asList("id", "name", "create_time");
List<String> allowedSorts = Arrays.asList("ASC", "DESC");
return allowedColumns.contains(column) && allowedSorts.contains(sort.toUpperCase());
}
不合法的参数直接抛异常,不让它走到SQL拼接。这个白名单要跟实际表字段严格对齐,加新字段记得同步更新,不然线上又会报错。
完整示例的Mapper大概是这样:
<select id="selectWithOrder" resultType="YourResultType">
SELECT * FROM your_table
<where>
<!-- 其他条件 -->
</where>
<if test="param.column != null and param.column != '' and param.sort != null and param.sort != ''">
<trim prefix="ORDER BY" suffixOverrides=",">
${param.column} ${param.sort}
</trim>
</if>
</select>
对应的接口和参数类:
@Mapper
public interface YourMapper {
List<YourResultType> selectWithOrder(@Param("param") SortParam param);
}
public class SortParam {
private String column;
private String sort;
// getters and setters
}
其实这类问题本身不复杂,但线上排错的时候可能会被日志里那段没有空格的SQL绕进去一两分钟,尤其是凌晨被报警叫起来。
一次把空格补上、加上 trim、做好白名单校验,后面这种排序相关的动态SQL就能踏实不少。
在MyBatis XML映射文件中,特殊符号如`<`、`>`、`&`等常常引发解析错误。本文将为你深入剖析两种核心转义方案:XML实体转义符与CDATA区块。我们将详细阐述它们的适用场景、优缺点,并提供实战建议,帮助你根据SQL复杂度灵活选择,确保XML文件正确解析,告别繁琐的转义工作,全面提升代码可维护性与团队开发效率。
深入剖析MyBatis动态SQL拼接中因字段名与排序方式间缺少空格导致的SQL语法错误。本文详细介绍手动添加空格、巧用`trim`标签的修复策略,并强调参数合法性验证与SQL注入防护的最佳实践,确保代码安全与可维护性。
当MyBatis多表关联查询返回的数据总是“缺斤少两”,甚至一对多只剩一条记录时,你是否感到束手无策?本文将化身技术侦探,深入剖析字段冲突、ResultMap配置陷阱及SQL逻辑漏洞,手把手教你运用别名、id标签和逐步验证法,彻底解决结果集缺失问题,确保数据完整无误。