MyBatis 的 XML 文件中特殊字符的处理

在 MyBatis 的 XML 文件中,大于符号 > 和小于符号 < 是 XML 的保留字符,当SQL语句中包含这些符号时需要进行特殊处理。以下是几种解决方案:

1、使用 XML 转义字符(推荐)

xml 复制代码
<!-- 使用 &gt; 表示大于号,&gt;= 表示大于等于号,&lt; 表示小于号,&lt;= 表示小于等于号, -->
<select id="selectByDateRange" resultType="Order">
    SELECT * FROM orders
    WHERE order_date &gt;= #{startDate}
    AND order_date &lt;= #{endDate}
</select>
xml 复制代码
<select id="selectByIdsWithCondition" resultType="User">
    SELECT * FROM users
    WHERE id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
    AND status &lt; 3  <!-- 必须转义 -->
    ORDER BY create_time DESC
</select>

2、使用 CDATA 区段包裹 SQL

xml 复制代码
<!-- 使用 <![CDATA[ ]]> 包裹 SQL -->
<select id="selectByDateRange" resultType="Order">
    <![CDATA[
    SELECT * FROM orders
    WHERE order_date >= #{startDate}
    AND order_date <= #{endDate}
    ]]>
</select>

3、动态 SQL 中的大/小于号同样处理

<if> 标签中使用

xml 复制代码
<select id="selectByCondition" resultType="User">
    SELECT * FROM users
    WHERE 1=1
    <if test="minAge != null">
        AND age &gt; #{minAge}
    </if>
    <if test="maxAge != null">
        AND age &lt; #{maxAge}
    </if>
    <if test="endTime != null">
        <![CDATA[ AND create_time < #{endTime} ]]>
    </if>
</select>

<choose> 标签中使用

xml 复制代码
<select id="selectByType" resultType="User">
    SELECT * FROM users
    <where>
        <choose>
            <when test="type == 'young'">
                AND age &lt; 30
            </when>
            <when test="type == 'middle'">
                <![CDATA[ AND age >= 30 AND age < 50 ]]>
            </when>
            <when test="type == 'senior'">
                AND age &gt;= 50
            </when>
        </choose>
    </where>
</select>

4、完整的转义字符对照表

bash 复制代码
符号	XML实体	描述	    示例
-------------------------------------------
>	&gt;	大于号	    age &gt; 18
>=	&gt;=	大于等于号	age &gt;= 18
<	&lt;	小于号	    age &lt; 30
<=	&lt;	小于等于号	age &lt;= 30
&	&amp;	和号	        name &amp; address
'	&apos;	单引号	    name = &apos;John&apos;
"	&quot;	双引号	    name = &quot;John&quot;

5、特殊场景处理

动态表名/列名中的小于号

xml 复制代码
<!-- 在 ${} 中也需要转义 -->
<select id="selectWithDynamicColumn" resultType="map">
    SELECT ${columnName} as value
    FROM ${tableName}
    WHERE ${columnName} &lt; #{threshold}
</select>

BETWEEN 和小于号的组合

xml 复制代码
<select id="selectByMultipleConditions" resultType="User">
    SELECT * FROM users
    WHERE 
        <!-- 使用 BETWEEN -->
        age BETWEEN #{minAge} AND #{maxAge}
        <!-- 结合小于号条件 -->
        <if test="maxScore != null">
            <![CDATA[ AND score < #{maxScore} ]]>
        </if>
        <!-- 使用转义字符 -->
        AND level &lt; #{maxLevel}
</select>

6、编写辅助函数

java 复制代码
// Java 工具类:自动转义 XML 特殊字符
public class XmlEscapeUtil {
    public static String escapeSqlForXml(String sql) {
        return sql.replace("&", "&amp;")
                  .replace("<", "&lt;")
                  .replace(">", "&gt;")
                  .replace("\"", "&quot;")
                  .replace("'", "'");
    }
    
    // 使用示例
    public static void main(String[] args) {
        String sql = "SELECT * FROM users WHERE age < 30 AND status > 0";
        System.out.println(escapeSqlForXml(sql));
        // 输出: SELECT * FROM users WHERE age &lt; 30 AND status &gt; 0
    }
}

最后:对于包含 <、> 的简单条件,使用 < 和 > 转义;对于包含大量特殊字符的复杂 SQL,使用 <!CDATA\[ ]> 包裹。

相关推荐
李昊哲小课1 天前
Spring Boot 4 旅游主题实战教程 阶段三:数据持久化
spring boot·后端·mybatis·旅游
datalover1 天前
MYBATIS=PLUS批量插入数据提效
mybatis
南城以南溫暖如初1472 天前
从零搭建24小时自助健身系统:技术选型与核心模块实战
java·spring boot·redis·mysql·vue·mybatis
小江的记录本2 天前
【ORM 框架】MyBatis-Plus 核心特性、条件构造器、分页插件、乐观锁插件(附《思维导图》、《问题排查与实践清单》和《面试高频考点汇总》)
java·windows·spring boot·python·spring·面试·mybatis
小江的记录本2 天前
【ORM框架】MyBatis核心原理、ORM思想、MyBatis vs JPA
java·数据库·后端·spring·spring cloud·oracle·mybatis
qq_485015213 天前
MyBatis-Plus 3.x FieldStrategy 作用
java·数据库·mybatis
布谷歌3 天前
如何自定义 MyBatis枚举处理器(EnumTypeHandler):分享从 “同包同名 shadow 覆盖” 到 “官方扩展点” 的重构经历
重构·mybatis
南城以南溫暖如初1473 天前
树洞交友系统架构设计与匿名聊天实战指南
java·spring boot·mysql·系统架构·vue·mybatis·交友
凯酱4 天前
MyBatis 中 OGNL 的使用:从入门到实战
java·tomcat·mybatis
蓝缘5 天前
解决main No MyBatis mapper was found in 的警告
mybatis