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\[ ]> 包裹。

相关推荐
禾小西15 小时前
Redis AOF 日志:宕机了,如何避免数据丢失?
java·redis·mybatis
天空鸟_时光不老20 小时前
09-RAG问答系统落地:从默认分割器的坑到Milvus召回调优
java·人工智能·spring boot·spring·spring cloud·maven·mybatis
西凉的悲伤20 小时前
MyBatis 中 association 与 collection 详解
java·mybatis
天空鸟_时光不老21 小时前
10-Agent安全隐患与SQL执行层加固
java·数据库·人工智能·sql·spring·maven·mybatis
jianjinwssy2 天前
MyBatis-Plus 从入门到实战:常用功能与核心原理
java·mybatis
ss2732 天前
AI全栈实战 | 3.6-01 数据库与 ORM:学过 MyBatis 再看 SQLAlchemy,才知道“半自动“和“全自动“差在哪
数据库·mybatis
代码什么用6 天前
使用javassist生成类 && MyBatis中接口代理机制及使用
mybatis
paopaokaka_luck6 天前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
韩曙亮6 天前
【JavaEE】MyBatis 基本用法 ⑤ ( 单条件查询 | 多条件查询 | 多条件动态查询 | 单条件动态查询 )
java·sql·java-ee·mybatis·mapper·sql映射
x-Achan6 天前
Redis实现方案:更新策略、穿透、雪崩、击穿、工具封装
java·spring boot·redis·spring·bootstrap·mybatis