mapper.xml中的大于等于、小于等于

你关注的是 MyBatis 的 mapper.xml 中如何正确处理「大于等于(>=)」和「小于等于(<=)」,以及相关的使用技巧(包括固定写法和动态优化),下面详细拆解:

一、核心问题:为什么不能直接在 mapper.xml 中写 >=<=

因为 <>XML 语言的特殊字符 (用于定义标签,如 <where><if>),直接写 zone_spacing >= #{zoneSpacingMin} 会导致 XML 解析器报错,无法识别该语法,因此需要通过「转义」或「CDATA 包裹」两种方式规避。

二、mapper.xml>=<= 的两种正确固定写法(常用)

写法1:使用 <![CDATA[]]> 包裹(推荐,直观易懂)

CDATA 块的作用是告诉 XML 解析器:「块内的内容是纯文本,无需解析标签,直接原样保留」,适合所有特殊字符场景。

xml 复制代码
<select id="getTrafficZoneFlow" resultMap="TrafficZoneInfoSpaceingResultMap">
    select
        zone_id,
        target_zone_id,
        zone_spacing,
        project_plan_id
    from
        traffic_zone_spacing
    <where>
        1=1
        <if test="zoneId != null">
            and zone_id = #{zoneId}
        </if>
        <if test="targetZoneId != null">
            and target_zone_id = #{targetZoneId}
        </if>
        <!-- 大于等于(>=):用 CDATA 包裹 -->
        <if test="zoneSpacingMin != null">
            and zone_spacing <![CDATA[>=]]> #{zoneSpacingMin}
        </if>
        <!-- 小于等于(<=):用 CDATA 包裹 -->
        <if test="zoneSpacingMax != null">
            and zone_spacing <![CDATA[<=]]> #{zoneSpacingMax}
        </if>
    </where>
</select>
写法2:使用 XML 转义字符替换(兼容所有XML解析器)

>=<= 替换为 XML 预定义的转义字符,也能避免解析报错,常用转义对应关系如下:

运算符 含义 XML 转义字符
> 大于 &gt;
>= 大于等于 &gt;=
< 小于 &lt;
<= 小于等于 &lt;=
& &amp;
" 双引号 &quot;

对应 SQL 示例:

xml 复制代码
<select id="getTrafficZoneFlow" resultMap="TrafficZoneInfoSpaceingResultMap">
    select
        zone_id,
        target_zone_id,
        zone_spacing,
        project_plan_id
    from
        traffic_zone_spacing
    <where>
        1=1
        <if test="zoneId != null">
            and zone_id = #{zoneId}
        </if>
        <if test="targetZoneId != null">
            and target_zone_id = #{targetZoneId}
        </if>
        <!-- 大于等于(>=):使用转义字符 &gt;= -->
        <if test="zoneSpacingMin != null">
            and zone_spacing &gt;= #{zoneSpacingMin}
        </if>
        <!-- 小于等于(<=):使用转义字符 &lt;= -->
        <if test="zoneSpacingMax != null">
            and zone_spacing &lt;= #{zoneSpacingMax}
        </if>
    </where>
</select>

三、进阶:将 >=<= 改为动态变量(灵活切换运算符,呼应你之前的需求)

如果需要将固定的 >=<= 改为可动态切换的变量(支持 >>=<<=),核心要点如下:

  1. 运算符必须用 ${} 拼接(#{} 会加引号,导致 SQL 语法错误)。
  2. <![CDATA[${运算符变量}]]> 包裹 ${},避免 XML 解析报错。
  3. Java 层做白名单校验,防止 SQL 注入。
完整示例(动态运算符)
1. DTO 新增运算符参数(带白名单校验)
java 复制代码
import java.util.Arrays;

public class TrafficZoneFlowQueryDTO {
    private Integer zoneId;
    private Integer targetZoneId;
    private Integer zoneSpacingMin;
    private Integer zoneSpacingMax;
    // 新增:小于等于/小于 运算符(默认 <=)
    private String zoneSpacingMaxOp = "<=";
    // 新增:大于等于/大于 运算符(默认 >=)
    private String zoneSpacingMinOp = ">=";

    // Getter/Setter 省略
    
    // 白名单校验:限制合法运算符,防止 SQL 注入
    public void setZoneSpacingMinOp(String zoneSpacingMinOp) {
        String[] validOps = {">", ">="};
        this.zoneSpacingMinOp = Arrays.asList(validOps).contains(zoneSpacingMinOp) 
            ? zoneSpacingMinOp : ">=";
    }

    public void setZoneSpacingMaxOp(String zoneSpacingMaxOp) {
        String[] validOps = {"<", "<="};
        this.zoneSpacingMaxOp = Arrays.asList(validOps).contains(zoneSpacingMaxOp) 
            ? zoneSpacingMaxOp : "<=";
    }
}
2. mapper.xml 动态拼接运算符
xml 复制代码
<select id="getTrafficZoneFlow" resultMap="TrafficZoneInfoSpaceingResultMap">
    select
        zone_id,
        target_zone_id,
        zone_spacing,
        project_plan_id
    from
        traffic_zone_spacing
    <where>
        1=1
        <if test="zoneId != null">
            and zone_id = #{zoneId}
        </if>
        <if test="targetZoneId != null">
            and target_zone_id = #{targetZoneId}
        </if>
        <!-- 动态大于/大于等于:CDATA 包裹 ${zoneSpacingMinOp} -->
        <if test="zoneSpacingMin != null">
            and zone_spacing <![CDATA[${zoneSpacingMinOp}]]> #{zoneSpacingMin}
        </if>
        <!-- 动态小于/小于等于:CDATA 包裹 ${zoneSpacingMaxOp} -->
        <if test="zoneSpacingMax != null">
            and zone_spacing <![CDATA[${zoneSpacingMaxOp}]]> #{zoneSpacingMax}
        </if>
    </where>
</select>

四、总结

  1. mapper.xml 中不能直接写 >=<=,需用「<![CDATA[]]> 包裹」或「XML 转义字符」。
  2. 固定运算符场景优先选 <![CDATA[]]>,直观易维护。
  3. 需灵活切换运算符时,用 ${} 拼接+Java 白名单校验,兼顾灵活性和安全性。
  4. 核心避坑:运算符拼接用 ${},数据传参用 #{},特殊字符用 <![CDATA[]]> 包裹。
相关推荐
2301_818732063 小时前
项目启动报错,错误指向xml 已解决
xml·java·数据库·后端·springboot
csdn2015_1 天前
generatorConfig.xml 配置 Controller、Service 完整教程
xml·mybatis
特立独行的猫a1 天前
从XML到Compose的UI变革:现代(2026)Android开发指南
android·xml·ui·compose·jetpack
spencer_tseng2 天前
Stream not available [SysDictDataMapper.xml]
xml·java
qq_297574672 天前
MySQL迁移到瀚高数据库 常用转换函数对照表(附XML示例,直接复用)
xml·数据库·mysql
好好研究3 天前
SpringBoot整合SpringMVC
xml·java·spring boot·后端·mvc
从此不归路4 天前
Qt5 进阶【12】JSON/XML 数据协议处理:与后端/配置文件的对接
xml·开发语言·c++·qt·json
方芯半导体5 天前
EtherCAT “通信 + 控制“ 的全国产化控制方案,ESC芯片(FCE1323)与国产MCU芯片功能板解析
xml·网络·单片机·嵌入式硬件·网络协议·机器人·自动化
好好研究5 天前
总结SSM设置欢迎页的方式
xml·java·后端·mvc
R-sz6 天前
mybatis的XML,如何多值匹配,支持单值(=)和多值(IN)查询
xml·mybatis