博客 / 詳情

返回

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

今天我們來聊聊 MyBatis XML 文件裏的 <![CDATA[ ]]> ,我依稀記得我第一次看到 <![CDATA[ ]]>,心想,這是個啥啊?

首先我們要明確:<![CDATA[ ]]>  不是 MyBatis 的專屬語法,而是 XML 的原生語法(全稱 Character Data,字符數據)。

XML 解析器 對某些特殊字符(比如 <、>、&、'、" 等)進行解析的時候,可能會將這些特殊字符 誤判,比如 將 < 識別為 XML 標籤的開始,等等。

<![CDATA[ ]]> 的核心作用:將包裹的內容標記為 "純文本",XML 解析器會跳過對其中內容的語法解析,直接 原樣保留,從而避免特殊字符與 XML 語法的衝突,保證 MyBatis 最終拿到的 SQL 是我們預期的樣子。

我們除了可以使用 <![CDATA[ ]]>,也可以使用 轉義字符

常用的 轉義字符對照

  • < → &lt;
  • > → &gt;
  • & → &amp;
  • " → &quot;
  • ' → &apos;

注意結尾的 ; 需要留着。

錯誤寫法

<!-- XML解析器會把 < 識別為標籤開始,直接報錯 -->
<select id="getUserByAge" resultType="User">
    SELECT * FROM user WHERE age < #{age}
</select>

使用 轉義 寫法

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

使用 CDATA 寫法

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

是不是使用 CDATA 的可讀性要高很多,所以推薦使用 CDATA,尤其是複雜SQL。

我們看個不是很複雜的SQL。

複雜SQL 轉義 寫法

<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>

複雜SQL CDATA 寫法

<select id="getUserBySpec" resultType="User">
    SELECT * FROM user
    <![CDATA[
        WHERE (age < #{age} OR salary > #{salary}) 
        AND (create_time >= #{startTime} OR update_time <= #{endTime})
    ]]>
</select>

MyBatis 高版本 對部分特殊字符做了兼容,比如直接寫 > 可能不報錯了。這是 "寬鬆解析",跨環境(比如不同 XML 解析器、不同數據庫驅動等)仍有可能出問題,推薦始終用 CDATA 保證兼容性

<![CDATA[ ]]> 是 MyBatis 中處理 SQL 語句與 XML 語法衝突的安全屏障。對包含 特殊字符 的 SQL 片段進行最小範圍的 CDATA 包裹,既保證了安全,又確保了 MyBatis 動態 SQL 功能的完整性。

手執煙火以謀生,心懷詩意以謀愛。-- 煙沙九洲

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.