MyBatis中大于等于小于等于的写法:XML转义字符的必知技巧

详解MyBatis XML中大于等于、小于等于等比较运算符的写法,解析XML转义字符的原因和使用场景

优兔GOGO
2025年11月6日
技术分享
MyBatisSQLXML大于等于小于等于转义字符

MyBatis中大于等于小于等于的写法:XML转义字符的必知技巧

在MyBatis的XML映射文件中写SQL时,经常会遇到需要使用大于等于、小于等于等比较运算符的情况。直接写>=<=会报错,这是为什么?应该怎么写?

这个问题困扰过很多MyBatis初学者。其实原因很简单:XML解析器会把<>当作标签的开始和结束符号,所以需要进行转义。掌握这些转义字符的写法,是使用MyBatis的基础技能。

比较运算符对照表

在MyBatis XML中,比较运算符需要使用转义字符,具体对照如下:

运算符XML写法说明
>&gt;]]>大于号
>=&gt;=]]>=大于等于
<&lt;<![CDATA[小于号
<=&lt;=<![CDATA[小于等于
&&amp;与符号
"&quot;双引号
'&apos;单引号

为什么需要转义?

XML解析器在解析XML文档时,会将<>识别为标签的开始和结束符号。如果在XML中直接写<>,解析器会认为这是标签的一部分,导致解析错误。

例如,如果直接写:

<if test="age >= 18">

XML解析器会认为age >= 18中的>是标签的开始,导致解析失败。

因此,需要使用转义字符&lt;&gt;来表示<>,或者使用CDATA区域来避免转义。

写法一:使用转义字符

使用转义字符是最常用的方法,直接在SQL中使用&lt;&gt;

示例1:查询年龄大于等于18的用户

<select id="selectAdults" resultType="User">
    SELECT * FROM users
    WHERE age &gt;= 18
</select>

示例2:查询价格小于等于100的商品

<select id="selectCheapProducts" resultType="Product">
    SELECT * FROM products
    WHERE price &lt;= 100
</select>

示例3:动态查询年龄范围

<select id="selectByAgeRange" 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>
</select>

示例4:多条件组合查询

<select id="selectByConditions" resultType="Order">
    SELECT * FROM orders
    WHERE 1=1
    <if test="minAmount != null">
        AND amount &gt;= #{minAmount}
    </if>
    <if test="maxAmount != null">
        AND amount &lt;= #{maxAmount}
    </if>
    <if test="status != null">
        AND status = #{status}
    </if>
</select>

示例5:在UPDATE中使用

<update id="updatePrice">
    UPDATE products
    SET price = #{newPrice}
    WHERE price &lt;= #{oldPrice}
</update>

写法二:使用CDATA区域

CDATA区域可以包含不需要解析的文本,适合包含大量SQL语句的情况:

示例1:使用CDATA包裹整个SQL

<select id="selectUsers" resultType="User">
    <![CDATA[
        SELECT * FROM users
        WHERE age >= 18
        AND age <= 65
    ]]>
</select>

示例2:CDATA与动态SQL结合

<select id="selectByRange" resultType="Product">
    SELECT * FROM products
    WHERE 1=1
    <if test="minPrice != null">
        <![CDATA[ AND price >= #{minPrice} ]]>
    </if>
    <if test="maxPrice != null">
        <![CDATA[ AND price <= #{maxPrice} ]]>
    </if>
</select>

示例3:复杂查询使用CDATA

<select id="selectComplex" resultType="Order">
    <![CDATA[
        SELECT o.*, u.name, p.product_name
        FROM orders o
        JOIN users u ON o.user_id = u.id
        JOIN products p ON o.product_id = p.id
        WHERE o.amount >= #{minAmount}
        AND o.amount <= #{maxAmount}
        AND o.create_time >= #{startTime}
        AND o.create_time <= #{endTime}
    ]]>
</select>

两种写法的对比

特性转义字符写法CDATA写法
可读性较差,&lt;&gt;不够直观较好,SQL保持原样
适用场景简单SQL,少量比较运算符复杂SQL,大量比较运算符
动态SQL容易与MyBatis动态标签结合需要小心处理,避免嵌套问题
维护性转义字符需要记忆SQL更接近原生写法

实际应用场景

场景1:分页查询

在分页查询中,经常需要根据ID范围查询:

<select id="selectByIdRange" resultType="User">
    SELECT * FROM users
    WHERE id &gt;= #{startId}
    AND id &lt;= #{endId}
    ORDER BY id
    LIMIT #{pageSize}
</select>

场景2:时间范围查询

查询某个时间范围内的数据:

<select id="selectByTimeRange" resultType="Log">
    SELECT * FROM logs
    WHERE create_time &gt;= #{startTime}
    AND create_time &lt;= #{endTime}
</select>

场景3:价格区间筛选

电商系统中常见的价格区间筛选:

<select id="selectByPriceRange" resultType="Product">
    SELECT * FROM products
    WHERE 1=1
    <if test="minPrice != null">
        AND price &gt;= #{minPrice}
    </if>
    <if test="maxPrice != null">
        AND price &lt;= #{maxPrice}
    </if>
    <if test="categoryId != null">
        AND category_id = #{categoryId}
    </if>
</select>

场景4:统计查询

统计某个范围内的数据:

<select id="countByRange" resultType="int">
    SELECT COUNT(*) FROM orders
    WHERE amount &gt;= #{minAmount}
    AND amount &lt;= #{maxAmount}
    AND status = 'completed'
</select>

常见错误和解决方案

错误1:直接使用>=<=

<!-- 错误写法 -->
<if test="age >= 18">
    AND age >= 18
</if>

错误原因:XML解析器会将>识别为标签的开始符号。

正确写法

<if test="age &gt;= 18">
    AND age &gt;= 18
</if>

错误2:CDATA区域嵌套问题

<!-- 错误写法 -->
<if test="age != null">
    <![CDATA[ AND age >= #{age} ]]>
</if>

错误原因:CDATA区域内的内容不会被解析,#{age}不会被替换。

正确写法

<if test="age != null">
    <![CDATA[ AND age >= ]]> #{age}
</if>

或者使用转义字符:

<if test="age != null">
    AND age &gt;= #{age}
</if>

错误3:混合使用导致混乱

<!-- 不推荐 -->
<select id="select">
    SELECT * FROM users
    WHERE age <![CDATA[ >= ]]> 18
    AND age &lt;= 65
</select>

建议:统一使用一种写法,要么全部用转义字符,要么全部用CDATA。

最佳实践建议

  1. 简单SQL使用转义字符:对于简单的SQL语句,使用&lt;&gt;更简洁。
  2. 复杂SQL使用CDATA:对于包含大量比较运算符的复杂SQL,使用CDATA区域可读性更好。
  3. 保持一致性:在同一个项目中,尽量统一使用一种写法,避免混用。
  4. 注意CDATA的限制:使用CDATA时,要注意参数占位符#{}的处理,避免嵌套问题。
  5. IDE支持:使用支持MyBatis的IDE插件,可以自动提示和检查转义字符。

掌握MyBatis中大于等于小于等于的写法,是使用MyBatis的基础。选择转义字符还是CDATA,取决于具体的场景和团队的编码规范。


🔗 相关工具

  • 本文介绍的技巧适用于所有MyBatis项目,无需额外工具