供应链 發表於 2026-2-11 21:15:00

MyBatis XML 里<![CDATA[ ]]>的使用

<p>今天我们来聊聊&nbsp;MyBatis XML 文件里的&nbsp;<strong>&lt;!]&gt;</strong> ,我依稀记得我第一次看到&nbsp;<strong>&lt;!]&gt;</strong>,心想,这是个啥啊?</p>
<p>首先我们要明确:<strong>&lt;!]&gt;&nbsp; 不是 MyBatis 的专属语法</strong>,而是 XML 的原生语法(全称 Character Data,字符数据)。</p>
<p><strong>XML 解析器&nbsp;</strong>对某些特殊字符(比如 <strong>&lt;、&gt;、&amp;、'、" </strong>等)进行解析的时候,可能会将这些特殊字符 <strong>误判</strong>,比如 将 <strong>&lt;</strong> 识别为 XML 标签的开始,等等。</p>
<p><strong>&lt;!]&gt;</strong> 的核心作用:<strong>将包裹的内容标记为 "纯文本"</strong>,XML 解析器会跳过对其中内容的语法解析,直接 <strong>原样保留</strong>,从而避免特殊字符与 XML 语法的冲突,保证 MyBatis 最终拿到的 SQL 是我们预期的样子。</p>
<p>我们除了可以使用&nbsp;<strong>&lt;!]&gt;</strong>,也可以使用 <strong>转义字符</strong>。</p>
<p>常用的 <strong>转义字符对照</strong>:</p>
<ul>
<li><strong>&lt; → &amp;lt;</strong></li>
<li><strong>&gt; → &amp;gt;</strong></li>
<li><strong>&amp; → &amp;amp;</strong></li>
<li><strong>" → &amp;quot;</strong></li>
<li><strong>' → &amp;apos;</strong></li>
</ul>
<p>注意结尾的 <strong>; </strong>需要留着。</p>
<p><strong>错误写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code>&lt;!-- XML解析器会把 &lt; 识别为标签开始,直接报错 --&gt;
&lt;select id="getUserByAge" resultType="User"&gt;
    SELECT * FROM user WHERE age &lt; #{age}
&lt;/select&gt;</code></pre>
<p><strong>使用 转义 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code>&lt;select id="getUserByAge" resultType="User"&gt;
    SELECT * FROM user WHERE age &amp;lt; #{age}
&lt;/select&gt;</code></pre>
<p><strong>使用 CDATA 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code>&lt;select id="getUserByAge" resultType="User"&gt;
    SELECT * FROM user WHERE &lt;!]&gt;
&lt;/select&gt;</code></pre>
<p>是不是使用&nbsp;<strong>CDATA </strong>的可读性要高很多,所以推荐使用&nbsp;<strong>CDATA</strong>,尤其是复杂SQL。</p>
<p>我们看个不是很复杂的SQL。</p>
<p><strong>复杂SQL 转义 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code>&lt;select id="getUserBySpec" resultType="User"&gt;
    SELECT * FROM user WHERE (age &amp;lt; #{age} OR salary &amp;gt; #{salary})
    AND (create_time gt;= #{startTime} OR update_time lt;= #{endTime})
&lt;/select&gt;</code></pre>
<p><strong>复杂SQL CDATA 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code>&lt;select id="getUserBySpec" resultType="User"&gt;
    SELECT * FROM user
    &lt;![CDATA[
      WHERE (age &lt; #{age} OR salary &gt; #{salary})
      AND (create_time &gt;= #{startTime} OR update_time &lt;= #{endTime})
    ]]&gt;
&lt;/select&gt;</code></pre>
<p><strong>MyBatis 高版本 </strong>对部分特殊字符做了兼容,比如直接写 <strong>&gt; </strong>可能不报错了。这是 "宽松解析",跨环境(比如不同 XML 解析器、不同数据库驱动等)仍有可能出问题,<strong>推荐始终用 CDATA 保证兼容性</strong>。</p>
<p><strong>&lt;!]&gt;</strong> 是 MyBatis 中处理 SQL 语句与 XML 语法冲突的安全屏障。对包含 <strong>特殊字符</strong> 的 SQL 片段进行最小范围的 <strong>CDATA 包裹</strong>,既保证了安全,又确保了 MyBatis 动态 SQL 功能的完整性。</p>
<p style="text-align: right"><span style="color: rgba(53, 152, 219, 1)">手执烟火以谋生,心怀诗意以谋爱。-- 烟沙九洲</span></p><br><br>
来源:https://www.cnblogs.com/yanshajiuzhou/p/19606003
頁: [1]
查看完整版本: MyBatis XML 里<![CDATA[ ]]>的使用