MyBatis XML中如何区分大于小于号在CDATA与HTML实体中的不同应用?

2026-04-29 13:103阅读0评论SEO资源
  • 内容介绍
  • 相关推荐

本文共计867个文字,预计阅读时间需要4分钟。

MyBatis XML中如何区分大于小于号在CDATA与HTML实体中的不同应用?

MyBatis 的 XML 映射文件本质上是标准 XML 文件,格式规范如下:

最简单、兼容性最好、也最不容易出错的做法就是老老实实用 HTML 实体:

  • 代替 <code><
  • > 代替 >
  • & 代替 &(如果条件里还带 &&

比如:<where><if test="age > 18">AND age > 18</if></where>

CDATA 块能包住 SQL,但别乱用在 test 属性里

<![CDATA[ ... ]]> 确实能让 XML 解析器跳过内容校验,适合包裹大段含 </> 的 SQL 片段(比如内联视图、复杂子查询)。但它只对「元素内容」生效,对属性值完全无效。

立即学习“前端免费学习笔记(深入)”;

下面这段是错的,XML 解析直接失败:

<if test="<![CDATA[age > 18]]>">

因为 test 是属性,CDATA 在属性里不被识别,反而会把 <![CDATA[ 当成非法标记开头。

正确用法只有一种场景:SQL 语句本体(即标签内部文本)需要写原生比较符时才用,例如:

<script> SELECT * FROM user WHERE <![CDATA[create_time > '2023-01-01' AND score < 100]]> </script>

为什么不用 这种数字字符引用?

和 <code> 功能等价,都是合法的 XML 字符引用。但实际项目中几乎没人用前者,原因很实在:

  • 可读性差:一眼看不出是小于号,团队协作时容易误判
  • IDE 支持弱:部分编辑器或 MyBatis 插件对数字引用识别不稳定,可能报红或补全异常
  • 无任何收益:没性能提升,也不解决新问题,纯属增加认知负担

所以,坚持用 /<code>> 就行,别折腾数字编码。

嵌套动态 SQL 里混用转义和 CDATA 容易翻车

<choose><when> 再套 <script> 时,有人会下意识在不同层级混用转义方式,结果逻辑看似对,实际执行 SQL 却漏了条件或语法错误。

关键原则就一条:同一层逻辑保持一致。推荐全部统一用实体转义,理由很实际:

  • 所有地方都支持,包括 testvalueprefix 等任意属性
  • 不会因 CDATA 开闭位置错位导致 XML 结构损坏(比如忘了闭合 ]]>
  • MyBatis 日志打印出来的 SQL 更干净,方便排查——实体转义在日志里会自动还原为符号,而 CDATA 块里的内容原样输出,有时反而难读

真正要小心的,其实是那些藏在字符串拼接里的隐式比较,比如 concat(name, '_') > 'admin_' ——这种地方漏转义,连报错都不会有,只会查不到数据。

本文共计867个文字,预计阅读时间需要4分钟。

MyBatis XML中如何区分大于小于号在CDATA与HTML实体中的不同应用?

MyBatis 的 XML 映射文件本质上是标准 XML 文件,格式规范如下:

最简单、兼容性最好、也最不容易出错的做法就是老老实实用 HTML 实体:

  • 代替 <code><
  • > 代替 >
  • & 代替 &(如果条件里还带 &&

比如:<where><if test="age > 18">AND age > 18</if></where>

CDATA 块能包住 SQL,但别乱用在 test 属性里

<![CDATA[ ... ]]> 确实能让 XML 解析器跳过内容校验,适合包裹大段含 </> 的 SQL 片段(比如内联视图、复杂子查询)。但它只对「元素内容」生效,对属性值完全无效。

立即学习“前端免费学习笔记(深入)”;

下面这段是错的,XML 解析直接失败:

<if test="<![CDATA[age > 18]]>">

因为 test 是属性,CDATA 在属性里不被识别,反而会把 <![CDATA[ 当成非法标记开头。

正确用法只有一种场景:SQL 语句本体(即标签内部文本)需要写原生比较符时才用,例如:

<script> SELECT * FROM user WHERE <![CDATA[create_time > '2023-01-01' AND score < 100]]> </script>

为什么不用 这种数字字符引用?

和 <code> 功能等价,都是合法的 XML 字符引用。但实际项目中几乎没人用前者,原因很实在:

  • 可读性差:一眼看不出是小于号,团队协作时容易误判
  • IDE 支持弱:部分编辑器或 MyBatis 插件对数字引用识别不稳定,可能报红或补全异常
  • 无任何收益:没性能提升,也不解决新问题,纯属增加认知负担

所以,坚持用 /<code>> 就行,别折腾数字编码。

嵌套动态 SQL 里混用转义和 CDATA 容易翻车

<choose><when> 再套 <script> 时,有人会下意识在不同层级混用转义方式,结果逻辑看似对,实际执行 SQL 却漏了条件或语法错误。

关键原则就一条:同一层逻辑保持一致。推荐全部统一用实体转义,理由很实际:

  • 所有地方都支持,包括 testvalueprefix 等任意属性
  • 不会因 CDATA 开闭位置错位导致 XML 结构损坏(比如忘了闭合 ]]>
  • MyBatis 日志打印出来的 SQL 更干净,方便排查——实体转义在日志里会自动还原为符号,而 CDATA 块里的内容原样输出,有时反而难读

真正要小心的,其实是那些藏在字符串拼接里的隐式比较,比如 concat(name, '_') > 'admin_' ——这种地方漏转义,连报错都不会有,只会查不到数据。