在使用 MyBatis 开发过程中,我们常常会将 SQL 语句书写在 XML 文件中(如 Mapper.xml)。由于 XML 本身的语法限制,常规 SQL 中的比较运算符(如 <, >, <=, >=, <>)无法直接书写,否则会造成 XML 解析错误。

本文将系统地介绍两种解决方案:XML 转义字符<![CDATA[]]>,并对其使用方法、注意事项及优缺点进行对比分析。

一、使用 XML 转义字符

在 XML 中,部分符号具有特殊含义,需要使用对应的转义字符:

符号

含义说明

转义字符

<

小于

&lt;

>

大于

&gt;

<=

小于等于

&lt;=

>=

大于等于

&gt;=

<>

不等于

&lt;&gt;

&

&amp;

'

单引号

&apos;

"

双引号

&quot;

📌 示例

SQL 原始语句:

SELECT * FROM user WHERE age <= 30;

MyBatis XML 写法:

<select id="getUser" resultType="User">
    SELECT * FROM user
    WHERE age &lt;= #{age}
</select>

使用转义字符注意事项

  • 转义字符前不能有空格(例如 & gt; 是非法的)

  • 转义字符必须以分号 ; 结尾

  • 大小写敏感(必须写成 &lt;,不能写成 &LT;

  • >=<= 中的 = 不能被转义,需要直接紧跟在转义字符后面,例如 &gt;=


二、使用 CDATA 块:<![CDATA[]]>

另一种更直观的方式是使用 CDATA 区块,告诉 XML 解析器“不要处理”其中的内容。CDATA(Character Data)是一种语法,能让我们在 XML 中嵌入原始 SQL,不进行任何转义。

📌 示例

SQL 原始语句:

SELECT * FROM user WHERE age <= 30;

MyBatis XML 写法:

<select id="getUser" resultType="User">
    SELECT * FROM user
    WHERE age <![CDATA[ <= ]]> #{age}
</select>

或完整嵌入:

<select id="getUser" resultType="User">
    <![CDATA[
    SELECT * FROM user
    WHERE age <= #{age}
    ]]>
</select>

使用 CDATA 注意事项

  • <![CDATA[ ... ]]> 不能嵌套

  • CDATA 必须是一个连续完整块,中间不能出现非法嵌套或换行

  • 所有内容原样输出,解析器不会处理其中的 SQL 字符


三、两种方法对比

特性

XML 转义字符

CDATA 块

编写难度

中(需记住对应字符)

低(原样书写)

可读性

较差(符号被转义)

较好(保留原始 SQL)

兼容性

性能影响

XML 解析器需额外处理转义

无需转义处理,解析更快

推荐场景

单个表达式条件

多行 SQL 或复杂条件语句


四、推荐实践

  • 简单判断语句推荐使用 XML 转义字符,如 &lt;, &gt;=

  • 整段复杂 SQL 或拼接语句推荐使用 <![CDATA[]]>,便于阅读与维护

  • 对于运维编写或文档输出的 SQL 模板,统一使用 CDATA 可提升可移植性


五、结语

在 MyBatis XML 中处理比较运算符符号的问题,是每一个 Java 后端开发者都会遇到的小坑。选择合适的写法,不仅能提升代码可读性,也能避免不必要的解析错误。

🧠 小技巧:如果你经常忘记转义字符含义,建议统一使用 <![CDATA[]]> 风格,保持 SQL 原样写法,简单直接,省心好记!