MyBatis XML 里<![CDATA[ ]]>的使用
<p>今天我们来聊聊 MyBatis XML 文件里的 <strong><!]></strong> ,我依稀记得我第一次看到 <strong><!]></strong>,心想,这是个啥啊?</p><p>首先我们要明确:<strong><!]> 不是 MyBatis 的专属语法</strong>,而是 XML 的原生语法(全称 Character Data,字符数据)。</p>
<p><strong>XML 解析器 </strong>对某些特殊字符(比如 <strong><、>、&、'、" </strong>等)进行解析的时候,可能会将这些特殊字符 <strong>误判</strong>,比如 将 <strong><</strong> 识别为 XML 标签的开始,等等。</p>
<p><strong><!]></strong> 的核心作用:<strong>将包裹的内容标记为 "纯文本"</strong>,XML 解析器会跳过对其中内容的语法解析,直接 <strong>原样保留</strong>,从而避免特殊字符与 XML 语法的冲突,保证 MyBatis 最终拿到的 SQL 是我们预期的样子。</p>
<p>我们除了可以使用 <strong><!]></strong>,也可以使用 <strong>转义字符</strong>。</p>
<p>常用的 <strong>转义字符对照</strong>:</p>
<ul>
<li><strong>< → &lt;</strong></li>
<li><strong>> → &gt;</strong></li>
<li><strong>& → &amp;</strong></li>
<li><strong>" → &quot;</strong></li>
<li><strong>' → &apos;</strong></li>
</ul>
<p>注意结尾的 <strong>; </strong>需要留着。</p>
<p><strong>错误写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code><!-- XML解析器会把 < 识别为标签开始,直接报错 -->
<select id="getUserByAge" resultType="User">
SELECT * FROM user WHERE age < #{age}
</select></code></pre>
<p><strong>使用 转义 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code><select id="getUserByAge" resultType="User">
SELECT * FROM user WHERE age &lt; #{age}
</select></code></pre>
<p><strong>使用 CDATA 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code><select id="getUserByAge" resultType="User">
SELECT * FROM user WHERE <!]>
</select></code></pre>
<p>是不是使用 <strong>CDATA </strong>的可读性要高很多,所以推荐使用 <strong>CDATA</strong>,尤其是复杂SQL。</p>
<p>我们看个不是很复杂的SQL。</p>
<p><strong>复杂SQL 转义 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code><select id="getUserBySpec" resultType="User">
SELECT * FROM user WHERE (age &lt; #{age} OR salary &gt; #{salary})
AND (create_time gt;= #{startTime} OR update_time lt;= #{endTime})
</select></code></pre>
<p><strong>复杂SQL CDATA 写法</strong>:</p>
<pre class="language-sql highlighter-hljs"><code><select id="getUserBySpec" resultType="User">
SELECT * FROM user
<![CDATA[
WHERE (age < #{age} OR salary > #{salary})
AND (create_time >= #{startTime} OR update_time <= #{endTime})
]]>
</select></code></pre>
<p><strong>MyBatis 高版本 </strong>对部分特殊字符做了兼容,比如直接写 <strong>> </strong>可能不报错了。这是 "宽松解析",跨环境(比如不同 XML 解析器、不同数据库驱动等)仍有可能出问题,<strong>推荐始终用 CDATA 保证兼容性</strong>。</p>
<p><strong><!]></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]